From 9df3faa43d9969446271aee014f333073fdc18b0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 27 Aug 2026 18:26:13 +0000 Subject: [PATCH] chore: update generated API types from latest spec --- docs/openapi/monitoring-api.json | 15081 ++++++++++++++++++++--------- src/devhelm/_generated.py | 1162 ++- 2 files changed, 11586 insertions(+), 4657 deletions(-) diff --git a/docs/openapi/monitoring-api.json b/docs/openapi/monitoring-api.json index 146f30f..edb2f6f 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,13 @@ } } }, - "/api/v1/monitors/{id}/results": { - "get": { + "/api/v1/monitors/{id}/pause": { + "post": { "tags": [ - "Check Results" + "Monitors" ], - "summary": "List raw check results", - "description": "Returns check results for the given monitor with optional time-range, region, and pass/fail filtering. Uses cursor-based pagination — pass the returned `cursor` value on subsequent requests to retrieve the next page. The cursor encodes the original time bounds, so `from`/`to` are ignored when a cursor is present.", - "operationId": "getResults", + "summary": "Pause a monitor", + "operationId": "pause", "parameters": [ { "name": "id", @@ -8050,84 +8524,34 @@ "type": "string", "format": "uuid" } - }, - { - "name": "from", - "in": "query", - "description": "Start of time range (ISO 8601, inclusive); defaults to 24 hours ago", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "End of time range (ISO 8601, inclusive); defaults to now", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response for pagination", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Maximum results per page (1–200)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 - }, - "example": 50 - }, - { - "name": "region", - "in": "query", - "description": "Filter by region (e.g. us-east)", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "passed", - "in": "query", - "description": "Filter by pass/fail status", - "required": false, - "schema": { - "type": "boolean" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MonitorOverlayRequest" + } + } + } + }, "responses": { "200": { - "description": "Paginated check results", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } }, "400": { - "description": "Invalid query parameters", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/CursorPageCheckResultDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -8143,21 +8567,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 +8629,14 @@ } } }, - "/api/v1/monitors/{id}/results/summary": { - "get": { + "/api/v1/monitors/{id}/publish": { + "post": { "tags": [ - "Check Results" + "Monitor definitions" ], - "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": "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", @@ -8222,40 +8646,35 @@ "type": "string", "format": "uuid" } - }, - { - "name": "chartWindow", - "in": "query", - "description": "Chart window: 24h returns hourly buckets, 7d/30d/90d return daily buckets", - "required": false, - "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishRevisionRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Results summary", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/ResultSummaryDto" + "$ref": "#/components/schemas/SingleValueResponseDefinitionHeadDto" } } } }, "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 +8690,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 +8752,13 @@ } } }, - "/api/v1/monitors/{id}/resume": { + "/api/v1/monitors/{id}/quarantine": { "post": { "tags": [ "Monitors" ], - "summary": "Resume a monitor (set enabled=true)", - "operationId": "resume", + "summary": "Quarantine a monitor", + "operationId": "quarantine", "parameters": [ { "name": "id", @@ -8351,6 +8770,16 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QuarantineMonitorRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", @@ -8445,14 +8874,13 @@ } } }, - "/api/v1/monitors/{id}/rotate-token": { + "/api/v1/monitors/{id}/release-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": "Release quarantine", + "operationId": "releaseQuarantine", "parameters": [ { "name": "id", @@ -8558,14 +8986,14 @@ } } }, - "/api/v1/monitors/{id}/status-pages": { + "/api/v1/monitors/{id}/results": { "get": { "tags": [ - "Monitors" + "Check Results" ], - "summary": "List status pages that contain this monitor as a component", - "description": "Returns all status pages where this monitor appears as a component, enabling the detail page to show 'Appears On' cross-links.", - "operationId": "listStatusPagesForMonitor", + "summary": "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", @@ -8575,25 +9003,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/TableValueResultStatusPageDto" + "$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" } } } @@ -8609,7 +9096,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": { @@ -8618,8 +9125,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": { @@ -8628,6 +9223,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": { @@ -8671,13 +9286,13 @@ } } }, - "/api/v1/monitors/{id}/tags": { - "get": { + "/api/v1/monitors/{id}/resume": { + "post": { "tags": [ "Monitors" ], - "summary": "Get all tags applied to a monitor", - "operationId": "getMonitorTags", + "summary": "Resume a paused monitor", + "operationId": "resume", "parameters": [ { "name": "id", @@ -8695,7 +9310,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -8781,13 +9396,16 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{id}/revisions": { + "get": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", - "operationId": "addMonitorTags", + "summary": "List revisions published in this monitor's environment", + "description": "Omits drafts never published here. Page size default 25.", + "operationId": "listRevisions", "parameters": [ { "name": "id", @@ -8797,25 +9415,23 @@ "type": "string", "format": "uuid" } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AddMonitorTagsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/TableValueResultRevisionDto" } } } @@ -8901,13 +9517,138 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/revisions/{revisionId}/test": { + "post": { "tags": [ - "Monitors" + "Monitor definitions" ], - "summary": "Remove tags from a monitor by their IDs", - "operationId": "removeMonitorTags", + "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", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "revisionId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } + ], + "responses": { + "202": { + "description": "Accepted", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseRunDto" + } + } + } + }, + "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}/rollback": { + "post": { + "tags": [ + "Monitor definitions" + ], + "summary": "Roll back Head to a prior revision", + "description": "Same Head UPDATE as publish; stores reason on the Head.", + "operationId": "rollback", "parameters": [ { "name": "id", @@ -8923,15 +9664,22 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RemoveMonitorTagsRequest" + "$ref": "#/components/schemas/RollbackRevisionRequest" } } }, "required": true }, "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseDefinitionHeadDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -9016,14 +9764,13 @@ } } }, - "/api/v1/monitors/{id}/test": { - "post": { + "/api/v1/monitors/{id}/rollback-preview": { + "get": { "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": "Preview rollback consequences for this environment", + "operationId": "rollbackPreview", "parameters": [ { "name": "id", @@ -9033,6 +9780,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "revisionId", + "in": "query", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { @@ -9041,7 +9797,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" + "$ref": "#/components/schemas/SingleValueResponseRollbackPreviewDto" } } } @@ -9129,14 +9885,14 @@ } } }, - "/api/v1/monitors/{id}/test-notifications": { + "/api/v1/monitors/{id}/rotate-token": { "post": { "tags": [ "Monitors" ], - "summary": "Send test notifications through the monitor's alert channels", - "description": "Sends a test alert to all specified channel IDs (must be channels attached to this monitor). If no channelIds are provided, tests all attached channels. Returns per-channel results.", - "operationId": "testNotifications", + "summary": "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", @@ -9148,23 +9904,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TestMonitorNotificationsRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTestChannelResult" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -9252,14 +9998,14 @@ } } }, - "/api/v1/monitors/{id}/uptime": { + "/api/v1/monitors/{id}/runs": { "get": { "tags": [ - "Check Results" + "Monitor Runs" ], - "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": "List runs for a code monitor", + "description": "Cursor page. Default limit 25.", + "operationId": "listMonitorRuns", "parameters": [ { "name": "id", @@ -9271,38 +10017,31 @@ } }, { - "name": "window", + "name": "params", "in": "query", - "description": "Time window for uptime calculation", - "required": false, + "required": true, "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d", - "90d" - ] + "$ref": "#/components/schemas/MonitorRunListParams" } } ], "responses": { "200": { - "description": "Uptime statistics", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/UptimeDto" + "$ref": "#/components/schemas/CursorPageRunDto" } } } }, "400": { - "description": "Invalid window parameter", + "description": "Bad request — the payload failed validation", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -9318,21 +10057,21 @@ } }, "403": { - "description": "Monitor does not belong to the caller's org", + "description": "Forbidden — the actor lacks permission for this resource", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { - "description": "Monitor not found", + "description": "Not found — the requested resource does not exist", "content": { - "*/*": { + "application/json": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseUptimeDto" + "$ref": "#/components/schemas/ErrorResponse" } } } @@ -9378,16 +10117,14 @@ } } } - } - }, - "/api/v1/monitors/{id}/versions": { - "get": { + }, + "post": { "tags": [ - "Monitors" + "Monitor Runs" ], - "summary": "List version history for a monitor", - "description": "Returns a paginated list of mutation snapshots for the monitor, newest first. Each version captures the full monitor config at the time of a PUT /monitors/{id} call.", - "operationId": "listVersions", + "summary": "Run now", + "description": "Persists a run in queued phase. 409 if no Head or any secret key is missing.", + "operationId": "runNow", "parameters": [ { "name": "id", @@ -9397,23 +10134,15 @@ "type": "string", "format": "uuid" } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { - "200": { - "description": "OK", + "202": { + "description": "Accepted", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -9501,14 +10230,13 @@ } } }, - "/api/v1/monitors/{id}/versions/{version}": { + "/api/v1/monitors/{id}/secret-requests": { "get": { "tags": [ - "Monitors" + "Monitor secret requests" ], - "summary": "Get a specific version snapshot for a monitor", - "description": "Returns the full monitor config snapshot captured at the given version number.", - "operationId": "getVersion", + "summary": "List secret requests for a monitor", + "operationId": "list_18", "parameters": [ { "name": "id", @@ -9518,15 +10246,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "version", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int32" - } } ], "responses": { @@ -9535,7 +10254,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9623,29 +10342,37 @@ } } }, - "/api/v1/monitors/{monitorId}/alert-channels": { + "/api/v1/monitors/{id}/secret-requests/{key}": { "put": { "tags": [ - "Monitor Alert Channels" + "Monitor secret requests" ], - "summary": "Replace the linked alert channel set for a monitor", - "operationId": "setChannels", + "summary": "Attach or clear a remapped secret for a key", + "operationId": "remap", "parameters": [ { - "name": "monitorId", + "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/SetAlertChannelsRequest" + "$ref": "#/components/schemas/RemapSecretRequest" } } }, @@ -9657,7 +10384,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseListUUID" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9745,16 +10472,16 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions": { + "/api/v1/monitors/{id}/secret-requests/rescan": { "post": { "tags": [ - "Monitor Assertions" + "Monitor secret requests" ], - "summary": "Add an assertion to a monitor", - "operationId": "add", + "summary": "Rescan secret requests from the active package", + "operationId": "rescan", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9763,23 +10490,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateAssertionRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSecretRequestsDto" } } } @@ -9867,25 +10584,126 @@ } } }, - "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { - "put": { + "/api/v1/monitors/{id}/session": { + "get": { "tags": [ - "Monitor Assertions" + "Monitor session" ], - "summary": "Update an assertion on a monitor", - "operationId": "update_10", + "summary": "Get the monitor session", + "operationId": "getSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" + } + } + } + }, + "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": [ + "Monitor session" + ], + "summary": "Create or update the monitor session", + "operationId": "putSession", + "parameters": [ { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { @@ -9898,7 +10716,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateAssertionRequest" + "$ref": "#/components/schemas/UpsertMonitorSessionRequest" } } }, @@ -9910,7 +10728,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorSessionDto" } } } @@ -9996,25 +10814,18 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/session/renew": { + "post": { "tags": [ - "Monitor Assertions" + "Monitor session" ], - "summary": "Remove an assertion from a monitor", - "operationId": "remove_1", + "summary": "Renew the monitor session", + "operationId": "renewSession", "parameters": [ { - "name": "monitorId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "assertionId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10024,8 +10835,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "202": { + "description": "Accepted", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseRunDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10110,16 +10928,16 @@ } } }, - "/api/v1/monitors/{monitorId}/auth": { - "put": { + "/api/v1/monitors/{id}/session/revoke": { + "post": { "tags": [ - "Monitor Auth" + "Monitor session" ], - "summary": "Update authentication config for a monitor", - "operationId": "update_9", + "summary": "Revoke the monitor session", + "operationId": "revokeSession", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10128,23 +10946,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" } } } @@ -10230,16 +11038,19 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{id}/status-pages": { + "get": { "tags": [ - "Monitor Auth" + "Monitors" ], - "summary": "Set authentication config for a monitor", - "operationId": "set", + "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", "required": true, "schema": { @@ -10248,23 +11059,13 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SetMonitorAuthRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" + "$ref": "#/components/schemas/TableValueResultStatusPageDto" } } } @@ -10350,16 +11151,18 @@ } } } - }, - "delete": { + } + }, + "/api/v1/monitors/{id}/tags": { + "get": { "tags": [ - "Monitor Auth" + "Monitors" ], - "summary": "Remove authentication config from a monitor", - "operationId": "remove", + "summary": "Get all tags applied to a monitor", + "operationId": "getMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", "required": true, "schema": { @@ -10369,8 +11172,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultTagDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -10453,21 +11263,17 @@ } } } - } - }, - "/api/v1/monitors/{monitorId}/policy": { - "get": { + }, + "post": { "tags": [ - "Incident Policies" + "Monitors" ], - "summary": "Get incident policy for a monitor", - "description": "Returns the trigger rules, confirmation settings, and recovery settings for the given monitor.", - "operationId": "get_5", + "summary": "Add tags to a monitor; supports existing tag IDs and inline creation of new tags", + "operationId": "addMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10475,13 +11281,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddMonitorTagsRequest" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Policy found", + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" + "$ref": "#/components/schemas/TableValueResultTagDto" } } } @@ -10517,11 +11333,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" } } } @@ -10568,18 +11384,16 @@ } } }, - "put": { + "delete": { "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": "Remove tags from a monitor by their IDs", + "operationId": "removeMonitorTags", "parameters": [ { - "name": "monitorId", + "name": "id", "in": "path", - "description": "Monitor UUID", "required": true, "schema": { "type": "string", @@ -10591,134 +11405,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateIncidentPolicyRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "Policy updated", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/IncidentPolicyDto" - } - } - } - }, - "400": { - "description": "Validation error in JSONB shape", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Monitor or policy not found", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseIncidentPolicyDto" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - } - } - } - }, - "/api/v1/monitors/bulk": { - "post": { - "tags": [ - "Monitors" - ], - "summary": "Bulk action on monitors", - "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", - "operationId": "bulkAction", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/BulkMonitorActionRequest" + "$ref": "#/components/schemas/RemoveMonitorTagsRequest" } } }, "required": true }, "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -10803,24 +11498,25 @@ } } }, - "/api/v1/monitors/test": { + "/api/v1/monitors/{id}/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", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MonitorTestRequest" - } + "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", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { "200": { "description": "OK", @@ -10915,19 +11611,18 @@ } } }, - "/api/v1/notification-dispatches": { - "get": { + "/api/v1/monitors/{id}/test-notifications": { + "post": { "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": "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": "incident_id", - "in": "query", - "description": "UUID of the incident to inspect", + "name": "id", + "in": "path", "required": true, "schema": { "type": "string", @@ -10935,13 +11630,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestMonitorNotificationsRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + "$ref": "#/components/schemas/TableValueResultTestChannelResult" } } } @@ -11029,14 +11734,13 @@ } } }, - "/api/v1/notification-dispatches/{id}": { - "get": { + "/api/v1/monitors/{id}/unmute": { + "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": "Clear mute overlay", + "operationId": "unmute", "parameters": [ { "name": "id", @@ -11054,7 +11758,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorDto" } } } @@ -11142,14 +11846,14 @@ } } }, - "/api/v1/notification-dispatches/{id}/acknowledge": { - "post": { + "/api/v1/monitors/{id}/uptime": { + "get": { "tags": [ - "Notification Dispatches" + "Check Results" ], - "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": "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", @@ -11159,25 +11863,40 @@ "type": "string", "format": "uuid" } + }, + { + "name": "window", + "in": "query", + "description": "Time window for uptime calculation", + "required": false, + "schema": { + "type": "string", + "enum": [ + "24h", + "7d", + "30d", + "90d" + ] + } } ], "responses": { "200": { - "description": "OK", + "description": "Uptime statistics", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$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" } } } @@ -11193,21 +11912,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" } } } @@ -11255,14 +11974,14 @@ } } }, - "/api/v1/notification-dispatches/{id}/unacknowledge": { - "post": { + "/api/v1/monitors/{id}/versions": { + "get": { "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": "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", @@ -11272,6 +11991,14 @@ "type": "string", "format": "uuid" } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } } ], "responses": { @@ -11280,7 +12007,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" + "$ref": "#/components/schemas/TableValueResultMonitorVersionDto" } } } @@ -11368,20 +12095,41 @@ } } }, - "/api/v1/notification-policies": { + "/api/v1/monitors/{id}/versions/{version}": { "get": { "tags": [ - "Notification Policies" + "Monitors" + ], + "summary": "Get a specific version snapshot for a monitor", + "description": "Returns the full monitor config snapshot captured at the given version number.", + "operationId": "getVersion", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "version", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } ], - "summary": "List all notification policies for the authenticated org", - "operationId": "list_7", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorVersionDto" } } } @@ -11467,30 +12215,43 @@ } } } - }, - "post": { + } + }, + "/api/v1/monitors/{monitorId}/alert-channels": { + "put": { "tags": [ - "Notification Policies" + "Monitor Alert Channels" + ], + "summary": "Replace the linked alert channel set for a monitor", + "operationId": "setChannels", + "parameters": [ + { + "name": "monitorId", + "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" + "$ref": "#/components/schemas/SetAlertChannelsRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseListUUID" } } } @@ -11578,16 +12339,16 @@ } } }, - "/api/v1/notification-policies/{id}": { - "get": { + "/api/v1/monitors/{monitorId}/assertions": { + "post": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Get a notification policy by ID", - "operationId": "getById_1", + "summary": "Add an assertion to a monitor", + "operationId": "add", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -11596,13 +12357,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateAssertionRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -11688,16 +12459,27 @@ } } } - }, + } + }, + "/api/v1/monitors/{monitorId}/assertions/{assertionId}": { "put": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Update a notification policy", - "operationId": "update_7", + "summary": "Update an assertion on a monitor", + "operationId": "update_10", "parameters": [ { - "name": "id", + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "assertionId", "in": "path", "required": true, "schema": { @@ -11710,7 +12492,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" + "$ref": "#/components/schemas/UpdateAssertionRequest" } } }, @@ -11722,7 +12504,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAssertionDto" } } } @@ -11811,13 +12593,22 @@ }, "delete": { "tags": [ - "Notification Policies" + "Monitor Assertions" ], - "summary": "Delete a notification policy", - "operationId": "delete_6", + "summary": "Remove an assertion from a monitor", + "operationId": "remove_1", "parameters": [ { - "name": "id", + "name": "monitorId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "assertionId", "in": "path", "required": true, "schema": { @@ -11913,71 +12704,41 @@ } } }, - "/api/v1/notification-policies/{id}/dispatches": { - "get": { + "/api/v1/monitors/{monitorId}/auth": { + "put": { "tags": [ - "Notification Policies" + "Monitor Auth" ], - "summary": "List dispatches (firing history) for a notification policy", - "description": "Additive optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50, and may include nextCursor. Response remains TableValueResult — no CursorPage swap.", - "operationId": "listDispatches", + "summary": "Update authentication config for a monitor", + "operationId": "update_9", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "since", - "in": "query", - "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "until", - "in": "query", - "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous nextCursor", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size 1–100 when windowing/paginating (default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateMonitorAuthRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -12063,18 +12824,16 @@ } } } - } - }, - "/api/v1/notification-policies/{id}/test": { + }, "post": { "tags": [ - "Notification Policies" + "Monitor Auth" ], - "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", - "operationId": "test_1", + "summary": "Set authentication config for a monitor", + "operationId": "set", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", "required": true, "schema": { @@ -12087,18 +12846,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TestNotificationPolicyRequest" + "$ref": "#/components/schemas/SetMonitorAuthRequest" } } - } + }, + "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" + "$ref": "#/components/schemas/SingleValueResponseMonitorAuthDto" } } } @@ -12184,56 +12944,27 @@ } } } - } - }, - "/api/v1/notifications": { - "get": { + }, + "delete": { "tags": [ - "Notifications" + "Monitor Auth" ], - "summary": "List notifications for the current user", - "operationId": "list_17", + "summary": "Remove authentication config from a monitor", + "operationId": "remove", "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" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -12318,27 +13049,36 @@ } } }, - "/api/v1/notifications/{id}/read": { - "put": { + "/api/v1/monitors/{monitorId}/policy": { + "get": { "tags": [ - "Notifications" + "Incident Policies" ], - "summary": "Mark a notification as read", - "operationId": "markRead", + "summary": "Get incident policy for a monitor", + "description": "Returns the trigger rules, confirmation settings, and recovery settings for the given monitor.", + "operationId": "get_5", "parameters": [ { - "name": "id", + "name": "monitorId", "in": "path", + "description": "Monitor UUID", "required": true, "schema": { - "type": "integer", - "format": "int64" + "type": "string", + "format": "uuid" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "Policy found", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/IncidentPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -12371,11 +13111,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" } } } @@ -12421,25 +13161,53 @@ } } } - } - }, - "/api/v1/notifications/read-all": { + }, "put": { "tags": [ - "Notifications" + "Incident Policies" ], - "summary": "Mark all notifications as read", - "operationId": "markAllRead", + "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": { - "204": { - "description": "No Content" + "200": { + "description": "Policy updated", + "content": { + "*/*": { + "schema": { + "$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" } } } @@ -12465,11 +13233,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" } } } @@ -12517,20 +13285,31 @@ } } }, - "/api/v1/notifications/unread-count": { - "get": { + "/api/v1/monitors/bulk": { + "post": { "tags": [ - "Notifications" + "Monitors" ], - "summary": "Get unread notification count", - "operationId": "unreadCount", + "summary": "Bulk action on monitors", + "description": "Applies PAUSE, RESUME, DELETE, ADD_TAG, or REMOVE_TAG to a list of monitors. Returns a partial-success response indicating which monitors succeeded and which failed.", + "operationId": "bulkAction", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkMonitorActionRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseLong" + "$ref": "#/components/schemas/SingleValueResponseBulkMonitorActionResult" } } } @@ -12618,20 +13397,30 @@ } } }, - "/api/v1/org": { - "get": { + "/api/v1/monitors/package-uploads": { + "post": { "tags": [ - "Organizations" + "Monitors" ], - "summary": "Get the current organization", - "operationId": "get_4", + "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/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/SingleValueResponsePackageUploadDto" } } } @@ -12717,18 +13506,21 @@ } } } - }, - "put": { + } + }, + "/api/v1/monitors/test": { + "post": { "tags": [ - "Organizations" + "Monitors" ], - "summary": "Update the current organization", - "operationId": "update_6", + "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/UpdateOrgDetailsRequest" + "$ref": "#/components/schemas/MonitorTestRequest" } } }, @@ -12740,7 +13532,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + "$ref": "#/components/schemas/SingleValueResponseMonitorTestResultDto" } } } @@ -12828,20 +13620,33 @@ } } }, - "/api/v1/resource-groups": { + "/api/v1/notification-dispatches": { "get": { "tags": [ - "Resource Groups" + "Notification Dispatches" + ], + "summary": "List all dispatches for an incident", + "description": "Returns all notification dispatches for the given incident that belong to the authenticated org's policies. Each dispatch includes delivery records for all associated channels.", + "operationId": "listByIncident", + "parameters": [ + { + "name": "incident_id", + "in": "query", + "description": "UUID of the incident to inspect", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "List all resource groups for the authenticated org with health summaries", - "operationId": "list_6", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultResourceGroupDto" + "$ref": "#/components/schemas/TableValueResultNotificationDispatchDto" } } } @@ -12927,30 +13732,34 @@ } } } - }, - "post": { + } + }, + "/api/v1/notification-dispatches/{id}": { + "get": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Create a new resource group", - "operationId": "create_7", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateResourceGroupRequest" - } + "summary": "Get a single dispatch with full escalation and delivery history", + "description": "Returns the dispatch state including current escalation step, acknowledgment info, and all delivery attempts made across every step.", + "operationId": "getById_3", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } - }, - "required": true - }, + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13038,14 +13847,14 @@ } } }, - "/api/v1/resource-groups/{id}": { - "get": { + "/api/v1/notification-dispatches/{id}/acknowledge": { + "post": { "tags": [ - "Resource Groups" + "Notification Dispatches" ], - "summary": "Get a resource group by id with member statuses and inherited settings", - "description": "Pass includeMetrics=true to enrich each member with 24h uptime, chart data, and latency metrics.", - "operationId": "get_3", + "summary": "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", @@ -13055,15 +13864,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "includeMetrics", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": false - } } ], "responses": { @@ -13072,7 +13872,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationDispatchDto" } } } @@ -13158,13 +13958,16 @@ } } } - }, - "put": { + } + }, + "/api/v1/notification-dispatches/{id}/unacknowledge": { + "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": "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", @@ -13176,23 +13979,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,27 +14071,25 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notification-policies": { + "get": { "tags": [ - "Resource Groups" - ], - "summary": "Delete a resource group (cascades to member rows)", - "operationId": "delete_5", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notification Policies" ], + "summary": "List all notification policies for the authenticated org", + "operationId": "list_7", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13381,34 +14172,30 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/health": { - "get": { + }, + "post": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Get the detailed health breakdown for a resource group", - "description": "Returns member counts, worst-of status, and threshold-based health evaluation. The thresholdStatus field is populated only when a health threshold is configured.", - "operationId": "getHealth", - "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/SingleValueResponseResourceGroupHealthDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13496,14 +14283,13 @@ } } }, - "/api/v1/resource-groups/{id}/matched-policies": { + "/api/v1/notification-policies/{id}": { "get": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "List notification policies that match this resource group", - "description": "Policies whose match rules evaluate true for a DEGRADED or DOWN group-origin INCIDENT_CREATED context on this resource group (includes paused)", - "operationId": "listMatchedPolicies", + "summary": "Get a notification policy by ID", + "operationId": "getById_1", "parameters": [ { "name": "id", @@ -13521,7 +14307,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13607,15 +14393,13 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/members": { - "post": { + }, + "put": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Add a monitor or service member to a resource group", - "operationId": "addMember_1", + "summary": "Update a notification policy", + "operationId": "update_7", "parameters": [ { "name": "id", @@ -13631,19 +14415,19 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + "$ref": "#/components/schemas/UpdateNotificationPolicyRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" + "$ref": "#/components/schemas/SingleValueResponseNotificationPolicyDto" } } } @@ -13729,15 +14513,13 @@ } } } - } - }, - "/api/v1/resource-groups/{id}/members/{memberId}": { + }, "delete": { "tags": [ - "Resource Groups" + "Notification Policies" ], - "summary": "Remove a member from a resource group", - "operationId": "removeMember_1", + "summary": "Delete a notification policy", + "operationId": "delete_6", "parameters": [ { "name": "id", @@ -13747,20 +14529,163 @@ "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/notification-policies/{id}/dispatches": { + "get": { + "tags": [ + "Notification Policies" + ], + "summary": "List dispatches (firing history) for a notification policy", + "description": "Optional query params: since/until/cursor/limit. When all are omitted, returns the full history (legacy). When any is set, defaults to a 30-day window and limit 50. Response is CursorPage (hasMore + nextCursor), the same wrapper used by other append-only history endpoints.", + "operationId": "listDispatches", + "parameters": [ { - "name": "memberId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "since", + "in": "query", + "description": "Inclusive lower bound (ISO-8601); defaults to now−30d when windowing", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "until", + "in": "query", + "description": "Exclusive upper bound (ISO-8601); defaults to now when windowing", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous nextCursor", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size 1–100 when windowing/paginating (default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageNotificationDispatchDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -13845,129 +14770,40 @@ } } }, - "/api/v1/secrets": { - "get": { + "/api/v1/notification-policies/{id}/test": { + "post": { "tags": [ - "Secrets" + "Notification Policies" ], - "summary": "List secrets", - "operationId": "list_5", - "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultSecretDto" - } - } - } - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "502": { - "description": "Bad gateway — an upstream provider returned an error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "503": { - "description": "Service unavailable — try again shortly", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } + "summary": "Dry-run: evaluate a policy's match rules against a supplied incident context", + "operationId": "test_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } - } - }, - "post": { - "tags": [ - "Secrets" ], - "summary": "Create secret", - "operationId": "create_6", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateSecretRequest" + "$ref": "#/components/schemas/TestNotificationPolicyRequest" } } - }, - "required": true + } }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/SingleValueResponseTestMatchResult" } } } @@ -14055,40 +14891,51 @@ } } }, - "/api/v1/secrets/{key}": { - "put": { + "/api/v1/notifications": { + "get": { "tags": [ - "Secrets" + "Notifications" ], - "summary": "Update secret", - "operationId": "update_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" + "type": "boolean", + "default": false } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSecretRequest" - } + }, + { + "name": "page", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 0 } }, - "required": true - }, + { + "name": "size", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 20 + } + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseSecretDto" + "$ref": "#/components/schemas/TableValueResultNotificationDto" } } } @@ -14174,20 +15021,23 @@ } } } - }, - "delete": { + } + }, + "/api/v1/notifications/{id}/read": { + "put": { "tags": [ - "Secrets" + "Notifications" ], - "summary": "Delete secret", - "operationId": "delete_4", + "summary": "Mark a notification as read", + "operationId": "markRead", "parameters": [ { - "name": "key", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "integer", + "format": "int64" } } ], @@ -14278,23 +15128,16 @@ } } }, - "/api/v1/service-subscriptions": { - "get": { + "/api/v1/notifications/read-all": { + "put": { "tags": [ - "Service Subscriptions" + "Notifications" ], - "summary": "List all service subscriptions for the organization", - "operationId": "list_16", + "summary": "Mark all notifications as read", + "operationId": "markAllRead", "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -14379,31 +15222,20 @@ } } }, - "/api/v1/service-subscriptions/{id}": { + "/api/v1/notifications/unread-count": { "get": { "tags": [ - "Service Subscriptions" - ], - "summary": "Get a subscription by its ID", - "operationId": "get_11", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - } + "Notifications" ], + "summary": "Get unread notification count", + "operationId": "unreadCount", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseLong" } } } @@ -14489,28 +15321,25 @@ } } } - }, - "delete": { + } + }, + "/api/v1/org": { + "get": { "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" - } - } + "Organizations" ], + "summary": "Get the current organization", + "operationId": "get_4", "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -14593,32 +15422,18 @@ } } } - } - }, - "/api/v1/service-subscriptions/{id}/alert-sensitivity": { - "patch": { + }, + "put": { "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" - } - } + "Organizations" ], + "summary": "Update the current organization", + "operationId": "update_6", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" + "$ref": "#/components/schemas/UpdateOrgDetailsRequest" } } }, @@ -14630,7 +15445,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/SingleValueResponseOrganizationDto" } } } @@ -14718,40 +15533,20 @@ } } }, - "/api/v1/service-subscriptions/{slug}": { - "post": { + "/api/v1/resource-groups": { + "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" - } - } + "Resource Groups" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ServiceSubscribeRequest" - } - } - } - }, + "summary": "List all resource groups for the authenticated org with health summaries", + "operationId": "list_6", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + "$ref": "#/components/schemas/TableValueResultResourceGroupDto" } } } @@ -14837,98 +15632,30 @@ } } } - } - }, - "/api/v1/services": { - "get": { + }, + "post": { "tags": [ - "Status Data" + "Resource Groups" ], - "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": "Create a new resource group", + "operationId": "create_7", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateResourceGroupRequest" + } } }, - { - "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", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageServiceCatalogDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15016,37 +15743,27 @@ } } }, - "/api/v1/services/{slugOrId}": { + "/api/v1/resource-groups/{id}": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get a single service by slug or UUID with current status, components, and recent incidents", - "description": "When ``summary=true``, the inline ``components`` list is trimmed to groups + showcase leaves + currently-impacted leaves + ungrouped leaves, and a ``componentsSummary`` block is added with the trimmed counts. Powers SSR for vendors with hundreds of components (Snowflake, Cloudflare, DigitalOcean) without OOM-ing the renderer. Default false for full back-compat.", - "operationId": "getService", + "summary": "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", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" - } - }, - { - "name": "summary", - "in": "query", - "description": "Return a curated subset of components (groups + showcase + impacted + ungrouped) and a componentsSummary block; default false", - "required": false, - "schema": { - "type": "boolean", - "default": false + "type": "string", + "format": "uuid" } }, { - "name": "publishedOnly", + "name": "includeMetrics", "in": "query", - "description": "Resolve only published services (curated public pSEO set); 404 otherwise. Default false", "required": false, "schema": { "type": "boolean", @@ -15060,7 +15777,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15146,72 +15863,41 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/components": { - "get": { + }, + "put": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List active components for a service with current status and inline uptime", - "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", - "operationId": "getComponents", + "summary": "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": "groupId", - "in": "query", - "description": "Restrict result to direct children of this group component id", - "required": false, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "search", - "in": "query", - "description": "Case-insensitive substring match on component name", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "page", - "in": "query", - "description": "Zero-based page index", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } - }, - { - "name": "size", - "in": "query", - "description": "Page size (default 25, max 100)", - "required": false, - "schema": { - "type": "integer", - "format": "int32" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateResourceGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceComponentDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupDto" } } } @@ -15297,80 +15983,27 @@ } } } - } - }, - "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { - "get": { + }, + "delete": { "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": "Delete a resource group (cascades to member rows)", + "operationId": "delete_5", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "componentId", + "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } - }, - { - "name": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, - "schema": { - "type": "string", - "format": "date" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit window end (ISO date); defaults to today", - "required": false, - "schema": { - "type": "string", - "format": "date" - } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -15455,56 +16088,22 @@ } } }, - "/api/v1/services/{slugOrId}/components/uptime": { + "/api/v1/resource-groups/{id}/health": { "get": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Batch daily uptime data for all leaf components", - "description": "Returns daily uptime for every active non-group component with uptime data, keyed by component ID. Replaces N individual per-component uptime calls with a single request. Supports either a preset ``period`` or an explicit ``from``/``to`` window (ISO yyyy-MM-dd, max 730 days). The explicit window wins when both are supplied — this is what powers the sliding 90-day navigator on the public uptime history page.", - "operationId": "getBatchComponentUptime", + "summary": "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": "period", - "in": "query", - "description": "Preset time window (used when ``from`` is omitted)", - "required": false, - "schema": { - "type": "string", - "enum": [ - "7d", - "30d", - "90d", - "1y" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit window start (ISO date); overrides ``period``", - "required": false, "schema": { "type": "string", - "format": "date" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit window end (ISO date); defaults to today", - "required": false, - "schema": { - "type": "string", - "format": "date" + "format": "uuid" } } ], @@ -15514,7 +16113,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupHealthDto" } } } @@ -15602,31 +16201,22 @@ } } }, - "/api/v1/services/{slugOrId}/days/{date}": { + "/api/v1/resource-groups/{id}/matched-policies": { "get": { "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": "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": "date", + "name": "id", "in": "path", - "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "date" + "format": "uuid" } } ], @@ -15636,7 +16226,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" + "$ref": "#/components/schemas/TableValueResultNotificationPolicyDto" } } } @@ -15724,61 +16314,41 @@ } } }, - "/api/v1/services/{slugOrId}/incidents": { - "get": { + "/api/v1/resource-groups/{id}/members": { + "post": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "List incident history for a service (paginated)", - "operationId": "listIncidents_1", + "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" - } - }, - { - "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" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddResourceGroupMemberRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseResourceGroupMemberDto" } } } @@ -15866,24 +16436,25 @@ } } }, - "/api/v1/services/{slugOrId}/incidents/{incidentId}": { - "get": { + "/api/v1/resource-groups/{id}/members/{memberId}": { + "delete": { "tags": [ - "Status Data" + "Resource Groups" ], - "summary": "Get incident detail with full update timeline", - "operationId": "getIncident_1", + "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": "incidentId", + "name": "memberId", "in": "path", "required": true, "schema": { @@ -15893,15 +16464,8 @@ } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -15986,21 +16550,21 @@ } } }, - "/api/v1/services/{slugOrId}/live-status": { + "/api/v1/revisions/{id}": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "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": "Get revision package", + "operationId": "get_12", "parameters": [ { - "name": "slugOrId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } } ], @@ -16010,7 +16574,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" + "$ref": "#/components/schemas/SingleValueResponseRevisionDto" } } } @@ -16098,45 +16662,28 @@ } } }, - "/api/v1/services/{slugOrId}/maintenances": { + "/api/v1/revisions/{id}/bundle": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "summary": "List scheduled maintenances for a service", - "operationId": "getScheduledMaintenances", + "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": "status", - "in": "query", - "description": "Filter by status (e.g. scheduled, in_progress, verifying, completed)", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string" - } + "type": "string", + "format": "uuid" } } ], "responses": { "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" - } - } - } + "description": "OK" }, "400": { "description": "Bad request — the payload failed validation", @@ -16221,40 +16768,30 @@ } } }, - "/api/v1/services/{slugOrId}/poll-results": { + "/api/v1/revisions/{id}/diff/{other}": { "get": { "tags": [ - "Status Data" + "Revisions" ], - "summary": "List poll results for a service (cursor-paginated)", - "operationId": "listPollResults", + "summary": "Compare two revisions (bounded hunks)", + "operationId": "diff", "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" + "type": "string", + "format": "uuid" } }, { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, + "name": "other", + "in": "path", + "required": true, "schema": { - "type": "integer", - "format": "int32", - "default": 50 + "type": "string", + "format": "uuid" } } ], @@ -16264,7 +16801,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageServicePollResultDto" + "$ref": "#/components/schemas/SingleValueResponseRevisionDiffDto" } } } @@ -16352,34 +16889,21 @@ } } }, - "/api/v1/services/{slugOrId}/poll-summary": { + "/api/v1/runs": { "get": { "tags": [ - "Status Data" + "Runs" ], - "summary": "Get aggregated poll metrics and chart data for a service", - "operationId": "getPollSummary", + "summary": "List code runs", + "description": "Org index. Default from=now-30m. Page size 50.", + "operationId": "listRuns", "parameters": [ { - "name": "slugOrId", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "window", + "name": "params", "in": "query", - "description": "Time window", - "required": false, + "required": true, "schema": { - "type": "string", - "enum": [ - "24h", - "7d", - "30d" - ] + "$ref": "#/components/schemas/RunListParams" } } ], @@ -16389,7 +16913,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" + "$ref": "#/components/schemas/TableValueResultRunDto" } } } @@ -16477,84 +17001,21 @@ } } }, - "/api/v1/services/{slugOrId}/status-events": { + "/api/v1/runs/{id}": { "get": { "tags": [ - "Status Data" + "Runs" ], - "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": "Get a run", + "operationId": "getRun", "parameters": [ { - "name": "slugOrId", + "name": "id", "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", - "enum": [ - "7d", - "30d", - "90d" - ] - } - }, - { - "name": "from", - "in": "query", - "description": "Explicit lower bound (ISO 8601); overrides period", - "required": false, - "schema": { - "type": "string", - "format": "date-time" - } - }, - { - "name": "to", - "in": "query", - "description": "Explicit upper bound (ISO 8601); default now", - "required": false, "schema": { "type": "string", - "format": "date-time" - } - }, - { - "name": "cursor", - "in": "query", - "description": "Opaque cursor from a previous response", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "description": "Page size (1–100, default 50)", - "required": false, - "schema": { - "type": "integer", - "format": "int32", - "default": 50 + "format": "uuid" } } ], @@ -16564,7 +17025,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/CursorPageStatusEventDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -16652,53 +17113,22 @@ } } }, - "/api/v1/services/{slugOrId}/uptime": { + "/api/v1/runs/{id}/artifacts": { "get": { "tags": [ - "Status Data" + "Runs" ], - "summary": "Get uptime statistics for a service", - "description": "Uptime data aggregated across active non-group components.", - "operationId": "getServiceUptime", + "summary": "List run artifacts", + "description": "Complete persist manifest for this run.", + "operationId": "listRunArtifacts", "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 +17138,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" + "$ref": "#/components/schemas/TableValueResultRunArtifactDto" } } } @@ -16793,61 +17223,25 @@ } } } - }, - "security": [ - { - "BearerAuth": [] - } - ] + } } }, - "/api/v1/services/incidents": { - "get": { + "/api/v1/runs/{id}/cancel": { + "post": { "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": "Request run cancel", + "description": "Sets cancel_requested; phase unchanged.", + "operationId": "cancelRun", "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 +17251,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseRunDto" } } } @@ -16945,23 +17339,29 @@ } } }, - "/api/v1/services/summary": { + "/api/v1/runs/{id}/cases": { "get": { "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": "List run cases with nested steps", + "operationId": "listRunCases", "parameters": [ { - "name": "publishedOnly", + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "params", "in": "query", - "description": "Aggregate only published services (curated public pSEO set); default false", - "required": false, + "required": true, "schema": { - "type": "boolean", - "default": false + "$ref": "#/components/schemas/RunCaseListParams" } } ], @@ -16971,7 +17371,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" + "$ref": "#/components/schemas/TableValueResultRunCaseDto" } } } @@ -17059,20 +17459,47 @@ } } }, - "/api/v1/status-pages": { + "/api/v1/runs/{id}/events": { "get": { "tags": [ - "Status Pages" + "Runs" + ], + "summary": "Stream run control events", + "operationId": "streamRunEvents", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "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" + } + } ], - "summary": "List status pages for the workspace", - "operationId": "list_4", "responses": { "200": { - "description": "OK", + "description": "Server-sent persist control events", "content": { - "*/*": { + "text/event-stream": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageDto" + "$ref": "#/components/schemas/RunEventDto" } } } @@ -17158,30 +17585,22 @@ } } } - }, - "post": { + } + }, + "/api/v1/secrets": { + "get": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Create a status page", - "operationId": "create_5", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageRequest" - } - } - }, - "required": true - }, + "summary": "List organization secrets", + "operationId": "list_5", "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/TableValueResultSecretDto" } } } @@ -17267,33 +17686,30 @@ } } } - } - }, - "/api/v1/status-pages/{id}": { - "get": { + }, + "post": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Get a status page", - "operationId": "get_2", - "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" + } } - } - ], + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -17379,21 +17795,22 @@ } } } - }, + } + }, + "/api/v1/secrets/{key}": { "put": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Update a status page", - "operationId": "update_3", + "summary": "Update secret", + "operationId": "update_4", "parameters": [ { - "name": "id", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], @@ -17401,7 +17818,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateStatusPageRequest" + "$ref": "#/components/schemas/UpdateSecretRequest" } } }, @@ -17413,7 +17830,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" + "$ref": "#/components/schemas/SingleValueResponseSecretDto" } } } @@ -17502,18 +17919,17 @@ }, "delete": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Delete a status page", - "operationId": "delete_3", + "summary": "Delete secret", + "operationId": "delete_4", "parameters": [ { - "name": "id", + "name": "key", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], @@ -17604,21 +18020,20 @@ } } }, - "/api/v1/status-pages/{id}/components": { + "/api/v1/secrets/{key}/audit": { "get": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "List all components", - "operationId": "listComponents", + "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" } } ], @@ -17628,7 +18043,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseSecretAuditDto" } } } @@ -17714,16 +18129,26 @@ } } } - }, - "post": { + } + }, + "/api/v1/secrets/{key}/environments/{environmentId}": { + "put": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Add a component to the status page", - "operationId": "createComponent", + "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": { @@ -17736,22 +18161,15 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentRequest" + "$ref": "#/components/schemas/WriteSecretEnvironmentValueRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -17836,50 +18254,131 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}": { - "put": { + "/api/v1/secrets/{key}/usage": { + "get": { "tags": [ - "Status Pages" + "Secrets" ], - "summary": "Update a component", - "operationId": "updateComponent", + "summary": "Secret usage across monitors", + "operationId": "usage", "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" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseSecretUsageDto" + } } } }, - "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/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/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/TableValueResultServiceSubscriptionDto" } } } @@ -17965,13 +18464,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/service-subscriptions/{id}": { + "get": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Remove a component from the status page", - "operationId": "deleteComponent", + "summary": "Get a subscription by its ID", + "operationId": "get_11", "parameters": [ { "name": "id", @@ -17981,20 +18482,18 @@ "type": "string", "format": "uuid" } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -18077,16 +18576,14 @@ } } } - } - }, - "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { - "get": { + }, + "delete": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "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": "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", @@ -18096,37 +18593,11 @@ "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", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -18211,14 +18682,14 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/override": { - "put": { + "/api/v1/service-subscriptions/{id}/alert-sensitivity": { + "patch": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Set a timed human status override on a component", - "description": "ASK-SP-1 / CHG-1. Effective currentStatus reflects the override until expiry or clear, unless an active incident takes precedence (incident > override > binding). Max expiry horizon is 24 hours.", - "operationId": "setComponentOverride", + "summary": "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", @@ -18228,22 +18699,13 @@ "type": "string", "format": "uuid" } - }, - { - "name": "componentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SetStatusPageComponentOverrideRequest" + "$ref": "#/components/schemas/UpdateAlertSensitivityRequest" } } }, @@ -18255,7 +18717,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -18341,40 +18803,42 @@ } } } - }, - "delete": { + } + }, + "/api/v1/service-subscriptions/{slug}": { + "post": { "tags": [ - "Status Pages" + "Service Subscriptions" ], - "summary": "Clear a timed human status override on a component", - "operationId": "clearComponentOverride", + "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", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "componentId", + "name": "slug", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceSubscribeRequest" + } + } + } + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceSubscriptionDto" } } } @@ -18462,41 +18926,86 @@ } } }, - "/api/v1/status-pages/{id}/components/{componentId}/uptime": { + "/api/v1/services": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get component uptime history from published incident windows", - "description": "Legacy incident-window rollup (source semantics: incident_window). Daily % is derived from published status-page incident windows, not probe checks. For measured check-based uptime use GET …/measured-uptime (ASK-SP-2 / CHG-2).", - "operationId": "componentUptime_1", + "summary": "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": "componentId", - "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" } }, { - "name": "days", + "name": "published", + "in": "query", + "description": "Filter by published status for pSEO pages", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "slaPublished", + "in": "query", + "description": "Filter by SLA page publication status", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "search", "in": "query", + "description": "Case-insensitive substring match on service name or slug", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "sort", + "in": "query", + "description": "Result ordering: 'recent' (default, newest first) or 'curated' (curated/recognizable first)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 20)", "required": false, "schema": { "type": "integer", "format": "int32", - "default": 90 + "default": 20 } } ], @@ -18506,7 +19015,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" + "$ref": "#/components/schemas/CursorPageServiceCatalogDto" } } } @@ -18594,38 +19103,55 @@ } } }, - "/api/v1/status-pages/{id}/components/reorder": { - "put": { + "/api/v1/services/{slugOrId}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Batch reorder components (and optionally move between groups)", - "operationId": "reorderComponents", + "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": "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 } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderComponentsRequest" + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseServiceDetailDto" + } } } }, - "required": true - }, - "responses": { - "204": { - "description": "No Content" - }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -18709,22 +19235,61 @@ } } }, - "/api/v1/status-pages/{id}/domains": { + "/api/v1/services/{slugOrId}/components": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List custom domains", - "operationId": "listDomains", + "summary": "List active components for a service with current status and inline uptime", + "description": "When ``groupId`` is supplied, only direct children of that group are returned — used by the pSEO renderer to lazy-load the leaves under a group that summary mode trimmed. Without ``groupId`` the response includes every active component for the service. Supports pagination via ``page``/``size`` and case-insensitive name search via ``search``.", + "operationId": "getComponents", "parameters": [ { - "name": "id", + "name": "slugOrId", "in": "path", "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "groupId", + "in": "query", + "description": "Restrict result to direct children of this group component id", + "required": false, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "search", + "in": "query", + "description": "Case-insensitive substring match on component name", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "page", + "in": "query", + "description": "Zero-based page index", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "name": "size", + "in": "query", + "description": "Page size (default 25, max 100)", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } } ], "responses": { @@ -18733,7 +19298,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultServiceComponentDto" } } } @@ -18819,41 +19384,77 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/components/{componentId}/uptime": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Add a custom domain", - "operationId": "addDomain", + "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/AddCustomDomainRequest" - } + }, + { + "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/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -18941,36 +19542,69 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}": { - "delete": { + "/api/v1/services/{slugOrId}/components/uptime": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Remove a custom domain", - "operationId": "removeDomain", + "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": "domainId", - "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" } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseBatchComponentUptimeDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19055,30 +19689,31 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}/primary": { - "post": { + "/api/v1/services/{slugOrId}/days/{date}": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Mark a verified custom domain as the page's primary host", - "operationId": "setPrimaryDomain", + "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": "domainId", + "name": "date", "in": "path", + "description": "UTC calendar day in ISO format (YYYY-MM-DD)", "required": true, "schema": { "type": "string", - "format": "uuid" + "format": "date" } } ], @@ -19088,7 +19723,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/SingleValueResponseServiceDayDetailDto" } } } @@ -19176,30 +19811,51 @@ } } }, - "/api/v1/status-pages/{id}/domains/{domainId}/verify": { - "post": { + "/api/v1/services/{slugOrId}/incidents": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Trigger domain verification check", - "operationId": "verifyDomain", + "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": "domainId", - "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" } } ], @@ -19209,7 +19865,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" } } } @@ -19297,16 +19953,24 @@ } } }, - "/api/v1/status-pages/{id}/groups": { + "/api/v1/services/{slugOrId}/incidents/{incidentId}": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List component groups with nested components", - "operationId": "listGroups", + "summary": "Get incident detail with full update timeline", + "operationId": "getIncident_1", "parameters": [ { - "name": "id", + "name": "slugOrId", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "incidentId", "in": "path", "required": true, "schema": { @@ -19321,7 +19985,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseServiceIncidentDetailDto" } } } @@ -19407,41 +20071,33 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/live-status": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Create a component group", - "operationId": "createGroup", + "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", + "name": "slugOrId", "in": "path", "required": true, "schema": { - "type": "string", - "format": "uuid" + "type": "string" } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/SingleValueResponseServiceLiveStatusDto" } } } @@ -19529,50 +20185,42 @@ } } }, - "/api/v1/status-pages/{id}/groups/{groupId}": { - "put": { + "/api/v1/services/{slugOrId}/maintenances": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update a component group", - "operationId": "updateGroup", + "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": "groupId", - "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/UpdateStatusPageComponentGroupRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" + "$ref": "#/components/schemas/TableValueResultScheduledMaintenanceDto" } } } @@ -19658,36 +20306,55 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/{slugOrId}/poll-results": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Delete a component group (components become ungrouped)", - "operationId": "deleteGroup", + "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": "groupId", - "in": "path", - "required": true, + "name": "cursor", + "in": "query", + "description": "ISO 8601 timestamp cursor from a previous response", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/CursorPageServicePollResultDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -19772,46 +20439,34 @@ } } }, - "/api/v1/status-pages/{id}/incidents": { + "/api/v1/services/{slugOrId}/poll-summary": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "List incidents for this status page (paginated)", - "operationId": "listIncidents", + "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", - "format": "uuid" + "type": "string" } }, { - "name": "status", + "name": "window", "in": "query", + "description": "Time window", "required": false, "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "enum": [ + "24h", + "7d", + "30d" + ] } } ], @@ -19821,7 +20476,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServicePollSummaryDto" } } } @@ -19907,41 +20562,96 @@ } } } - }, - "post": { + } + }, + "/api/v1/services/{slugOrId}/status-events": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Create a status page incident (manual)", - "operationId": "createIncident", + "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" + ] } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" - } + }, + { + "name": "from", + "in": "query", + "description": "Explicit lower bound (ISO 8601); overrides period", + "required": false, + "schema": { + "type": "string", + "format": "date-time" } }, - "required": true - }, + { + "name": "to", + "in": "query", + "description": "Explicit upper bound (ISO 8601); default now", + "required": false, + "schema": { + "type": "string", + "format": "date-time" + } + }, + { + "name": "cursor", + "in": "query", + "description": "Opaque cursor from a previous response", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "description": "Page size (1–100, default 50)", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 50 + } + } + ], "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/CursorPageStatusEventDto" } } } @@ -20029,30 +20739,53 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "/api/v1/services/{slugOrId}/uptime": { "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Get incident details with timeline", - "operationId": "getIncident", + "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": "incidentId", - "in": "path", - "required": true, + "name": "granularity", + "in": "query", + "description": "Bucket granularity", + "required": false, "schema": { "type": "string", - "format": "uuid" + "enum": [ + "hourly", + "daily", + "monthly" + ] } } ], @@ -20062,7 +20795,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseServiceUptimeResponse" } } } @@ -20147,51 +20880,71 @@ } } } - } - }, - "put": { + }, + "security": [ + { + "BearerAuth": [] + } + ] + } + }, + "/api/v1/services/incidents": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Update an incident", - "operationId": "updateIncident", + "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": "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" + ] } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" - } + }, + { + "name": "category", + "in": "query", + "description": "Filter by service category", + "required": false, + "schema": { + "type": "string" } }, - "required": true - }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultServiceIncidentDto" } } } @@ -20277,36 +21030,38 @@ } } } - }, - "delete": { + } + }, + "/api/v1/services/summary": { + "get": { "tags": [ - "Status Pages" + "Status Data" ], - "summary": "Delete an incident", - "operationId": "deleteIncident", + "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": "incidentId", - "in": "path", - "required": true, + "name": "publishedOnly", + "in": "query", + "description": "Aggregate only published services (curated public pSEO set); default false", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "boolean", + "default": false } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseGlobalStatusSummaryDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -20391,36 +21146,23 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { - "post": { + "/api/v1/status-pages": { + "get": { "tags": [ "Status Pages" ], - "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", - "operationId": "dismissIncident", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "incidentId", - "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", @@ -20503,51 +21245,30 @@ } } } - } - }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { + }, "post": { "tags": [ "Status Pages" ], - "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" - } - }, - { - "name": "incidentId", - "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/PublishStatusPageIncidentRequest" + "$ref": "#/components/schemas/CreateStatusPageRequest" } } - } + }, + "required": true }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -20635,13 +21356,13 @@ } } }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { - "post": { + "/api/v1/status-pages/{id}": { + "get": { "tags": [ "Status Pages" ], - "summary": "Post an incident timeline update", - "operationId": "postIncidentUpdate", + "summary": "Get a status page", + "operationId": "get_2", "parameters": [ { "name": "id", @@ -20651,34 +21372,15 @@ "type": "string", "format": "uuid" } - }, - { - "name": "incidentId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], - "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/SingleValueResponseStatusPageDto" } } } @@ -20764,15 +21466,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { - "patch": { + }, + "put": { "tags": [ "Status Pages" ], - "summary": "Edit an existing incident timeline update body", - "operationId": "patchIncidentUpdate", + "summary": "Update a status page", + "operationId": "update_3", "parameters": [ { "name": "id", @@ -20782,31 +21482,13 @@ "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" + "$ref": "#/components/schemas/UpdateStatusPageRequest" } } }, @@ -20818,7 +21500,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageDto" } } } @@ -20904,15 +21586,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/layout/reorder": { - "put": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Reorder page-level layout: groups and ungrouped components share one ordering", - "operationId": "reorderLayout", + "summary": "Delete a status page", + "operationId": "delete_3", "parameters": [ { "name": "id", @@ -20924,16 +21604,6 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReorderPageLayoutRequest" - } - } - }, - "required": true - }, "responses": { "204": { "description": "No Content" @@ -21021,13 +21691,13 @@ } } }, - "/api/v1/status-pages/{id}/maintenance": { + "/api/v1/status-pages/{id}/components": { "get": { "tags": [ "Status Pages" ], - "summary": "List maintenance windows for this status page (paginated)", - "operationId": "listMaintenance", + "summary": "List all components", + "operationId": "listComponents", "parameters": [ { "name": "id", @@ -21037,31 +21707,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "status", - "in": "query", - "required": false, - "schema": { - "type": "array", - "items": { - "type": "string", - "enum": [ - "INVESTIGATING", - "IDENTIFIED", - "MONITORING", - "RESOLVED" - ] - } - } - }, - { - "name": "pageable", - "in": "query", - "required": true, - "schema": { - "$ref": "#/components/schemas/Pageable" - } } ], "responses": { @@ -21070,7 +21715,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentDto" } } } @@ -21161,8 +21806,8 @@ "tags": [ "Status Pages" ], - "summary": "Schedule a maintenance window", - "operationId": "createMaintenance", + "summary": "Add a component to the status page", + "operationId": "createComponent", "parameters": [ { "name": "id", @@ -21178,7 +21823,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateStatusPageMaintenanceRequest" + "$ref": "#/components/schemas/CreateStatusPageComponentRequest" } } }, @@ -21190,7 +21835,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -21278,132 +21923,13 @@ } } }, - "/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" - } - } - } - } - } - }, + "/api/v1/status-pages/{id}/components/{componentId}": { "put": { "tags": [ "Status Pages" ], - "summary": "Update a maintenance window", - "operationId": "updateMaintenance", + "summary": "Update a component", + "operationId": "updateComponent", "parameters": [ { "name": "id", @@ -21415,7 +21941,7 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -21428,7 +21954,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" + "$ref": "#/components/schemas/UpdateStatusPageComponentRequest" } } }, @@ -21440,7 +21966,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -21531,8 +22057,8 @@ "tags": [ "Status Pages" ], - "summary": "Cancel a maintenance window", - "operationId": "deleteMaintenance", + "summary": "Remove a component from the status page", + "operationId": "deleteComponent", "parameters": [ { "name": "id", @@ -21544,7 +22070,7 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -21640,13 +22166,14 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { - "post": { + "/api/v1/status-pages/{id}/components/{componentId}/measured-uptime": { + "get": { "tags": [ "Status Pages" ], - "summary": "Dismiss a draft maintenance window", - "operationId": "dismissMaintenance", + "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", @@ -21658,18 +22185,35 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } + }, + { + "name": "days", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 90 + } } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageMeasuredComponentUptimeDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -21754,13 +22298,14 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/publish": { - "post": { + "/api/v1/status-pages/{id}/components/{componentId}/override": { + "put": { "tags": [ "Status Pages" ], - "summary": "Publish a draft maintenance window", - "operationId": "publishMaintenance", + "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", @@ -21772,7 +22317,7 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -21785,10 +22330,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" + "$ref": "#/components/schemas/SetStatusPageComponentOverrideRequest" } } - } + }, + "required": true }, "responses": { "200": { @@ -21796,7 +22342,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentDto" } } } @@ -21882,15 +22428,13 @@ } } } - } - }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { - "post": { + }, + "delete": { "tags": [ "Status Pages" ], - "summary": "Post a maintenance window timeline update", - "operationId": "postMaintenanceUpdate", + "summary": "Clear a timed human status override on a component", + "operationId": "clearComponentOverride", "parameters": [ { "name": "id", @@ -21902,7 +22446,7 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -21911,23 +22455,13 @@ } } ], - "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/SingleValueResponseStatusPageComponentDto" } } } @@ -22015,13 +22549,14 @@ } } }, - "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { - "patch": { + "/api/v1/status-pages/{id}/components/{componentId}/uptime": { + "get": { "tags": [ "Status Pages" ], - "summary": "Edit an existing maintenance timeline update body", - "operationId": "patchMaintenanceUpdate", + "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", @@ -22033,7 +22568,7 @@ } }, { - "name": "windowId", + "name": "componentId", "in": "path", "required": true, "schema": { @@ -22042,32 +22577,23 @@ } }, { - "name": "updateId", - "in": "path", - "required": true, + "name": "days", + "in": "query", + "required": false, "schema": { - "type": "string", - "format": "uuid" + "type": "integer", + "format": "int32", + "default": 90 } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" - } - } - }, - "required": true - }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" + "$ref": "#/components/schemas/TableValueResultComponentUptimeDayDto" } } } @@ -22155,14 +22681,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries": { - "get": { + "/api/v1/status-pages/{id}/components/reorder": { + "put": { "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": "Batch reorder components (and optionally move between groups)", + "operationId": "reorderComponents", "parameters": [ { "name": "id", @@ -22172,42 +22697,22 @@ "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" - } + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReorderComponentsRequest" } } }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, "400": { "description": "Bad request — the payload failed validation", "content": { @@ -22291,13 +22796,13 @@ } } }, - "/api/v1/status-pages/{id}/notification-deliveries/{deliveryId}": { + "/api/v1/status-pages/{id}/domains": { "get": { "tags": [ "Status Pages" ], - "summary": "Get a notification delivery receipt", - "operationId": "getNotificationDelivery", + "summary": "List custom domains", + "operationId": "listDomains", "parameters": [ { "name": "id", @@ -22307,15 +22812,6 @@ "type": "string", "format": "uuid" } - }, - { - "name": "deliveryId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], "responses": { @@ -22324,7 +22820,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/TableValueResultStatusPageCustomDomainDto" } } } @@ -22410,16 +22906,13 @@ } } } - } - }, - "/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", + "summary": "Add a custom domain", + "operationId": "addDomain", "parameters": [ { "name": "id", @@ -22429,24 +22922,25 @@ "type": "string", "format": "uuid" } - }, - { - "name": "deliveryId", - "in": "path", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddCustomDomainRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageNotificationDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -22534,13 +23028,13 @@ } } }, - "/api/v1/status-pages/{id}/subscribers": { - "get": { + "/api/v1/status-pages/{id}/domains/{domainId}": { + "delete": { "tags": [ "Status Pages" ], - "summary": "List subscribers including awaiting confirmation (paginated)", - "operationId": "listSubscribers", + "summary": "Remove a custom domain", + "operationId": "removeDomain", "parameters": [ { "name": "id", @@ -22552,24 +23046,18 @@ } }, { - "name": "pageable", - "in": "query", + "name": "domainId", + "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 +23140,15 @@ } } } - }, + } + }, + "/api/v1/status-pages/{id}/domains/{domainId}/primary": { "post": { "tags": [ "Status Pages" ], - "summary": "Add a subscriber; requireConfirmation=true for EMAIL double opt-in, omit/false confirms immediately", - "operationId": "addSubscriber", + "summary": "Mark a verified custom domain as the page's primary host", + "operationId": "setPrimaryDomain", "parameters": [ { "name": "id", @@ -22668,25 +23158,24 @@ "type": "string", "format": "uuid" } + }, + { + "name": "domainId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/AdminAddSubscriberRequest" - } - } - }, - "required": true - }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseStatusPageSubscriberDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" } } } @@ -22774,13 +23263,13 @@ } } }, - "/api/v1/status-pages/{id}/subscribers/{subscriberId}": { - "delete": { + "/api/v1/status-pages/{id}/domains/{domainId}/verify": { + "post": { "tags": [ "Status Pages" ], - "summary": "Remove a subscriber", - "operationId": "removeSubscriber", + "summary": "Trigger domain verification check", + "operationId": "verifyDomain", "parameters": [ { "name": "id", @@ -22792,7 +23281,7 @@ } }, { - "name": "subscriberId", + "name": "domainId", "in": "path", "required": true, "schema": { @@ -22802,8 +23291,15 @@ } ], "responses": { - "204": { - "description": "No Content" + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageCustomDomainDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -22888,20 +23384,21 @@ } } }, - "/api/v1/tags": { + "/api/v1/status-pages/{id}/groups": { "get": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "List tags for the authenticated organization", - "operationId": "list_3", + "summary": "List component groups with nested components", + "operationId": "listGroups", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" } } ], @@ -22911,7 +23408,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultTagDto" + "$ref": "#/components/schemas/TableValueResultStatusPageComponentGroupDto" } } } @@ -23000,15 +23497,26 @@ }, "post": { "tags": [ - "Tags" + "Status Pages" + ], + "summary": "Create a component group", + "operationId": "createGroup", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "summary": "Create a new tag", - "operationId": "create_4", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTagRequest" + "$ref": "#/components/schemas/CreateStatusPageComponentGroupRequest" } } }, @@ -23020,7 +23528,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -23108,13 +23616,13 @@ } } }, - "/api/v1/tags/{id}": { - "get": { + "/api/v1/status-pages/{id}/groups/{groupId}": { + "put": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Get a tag by ID", - "operationId": "getById", + "summary": "Update a component group", + "operationId": "updateGroup", "parameters": [ { "name": "id", @@ -23124,15 +23632,34 @@ "type": "string", "format": "uuid" } + }, + { + "name": "groupId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageComponentGroupRequest" + } + } + }, + "required": true + }, "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageComponentGroupDto" } } } @@ -23219,12 +23746,12 @@ } } }, - "put": { + "delete": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Update a tag's name and/or color", - "operationId": "update_2", + "summary": "Delete a component group (components become ungrouped)", + "operationId": "deleteGroup", "parameters": [ { "name": "id", @@ -23234,25 +23761,154 @@ "type": "string", "format": "uuid" } + }, + { + "name": "groupId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateTagRequest" + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "description": "Bad request — the payload failed validation", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } } } }, - "required": true - }, + "401": { + "description": "Unauthorized — missing or invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "403": { + "description": "Forbidden — the actor lacks permission for this resource", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "404": { + "description": "Not found — the requested resource does not exist", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "409": { + "description": "Conflict — the request collides with current resource state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "500": { + "description": "Internal server error — see the message field for details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "502": { + "description": "Bad gateway — an upstream provider returned an error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + }, + "503": { + "description": "Service unavailable — try again shortly", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ErrorResponse" + } + } + } + } + } + } + }, + "/api/v1/status-pages/{id}/incidents": { + "get": { + "tags": [ + "Status Pages" + ], + "summary": "List incidents for this status page (paginated)", + "operationId": "listIncidents", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "status", + "in": "query", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] + } + } + }, + { + "name": "pageable", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Pageable" + } + } + ], "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseTagDto" + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" } } } @@ -23339,12 +23995,12 @@ } } }, - "delete": { + "post": { "tags": [ - "Tags" + "Status Pages" ], - "summary": "Delete a tag (cascades to all monitor associations)", - "operationId": "delete_2", + "summary": "Create a status page incident (manual)", + "operationId": "createIncident", "parameters": [ { "name": "id", @@ -23356,9 +24012,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStatusPageIncidentRequest" + } + } + }, + "required": true + }, "responses": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -23443,21 +24116,40 @@ } } }, - "/api/v1/vaults/rotate": { - "post": { + "/api/v1/status-pages/{id}/incidents/{incidentId}": { + "get": { "tags": [ - "Vault" + "Status Pages" + ], + "summary": "Get incident details with timeline", + "operationId": "getIncident", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + } ], - "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/SingleValueResponseStatusPageIncidentDto" } } } @@ -23543,32 +24235,50 @@ } } } - } - }, - "/api/v1/webhooks": { - "get": { + }, + "put": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "List webhook endpoints for the authenticated org", - "operationId": "list_2", + "summary": "Update an incident", + "operationId": "updateIncident", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "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/TableValueResultWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -23655,32 +24365,35 @@ } } }, - "post": { + "delete": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Register a new webhook endpoint", - "operationId": "create_3", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWebhookEndpointRequest" - } + "summary": "Delete an incident", + "operationId": "deleteIncident", + "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": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } + } + ], + "responses": { + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23765,13 +24478,13 @@ } } }, - "/api/v1/webhooks/{id}": { - "get": { + "/api/v1/status-pages/{id}/incidents/{incidentId}/dismiss": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Get a single webhook endpoint", - "operationId": "get_1", + "summary": "Dismiss a draft incident (soft-deletes: resolves without publishing)", + "operationId": "dismissIncident", "parameters": [ { "name": "id", @@ -23781,18 +24494,20 @@ "type": "string", "format": "uuid" } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -23875,13 +24590,15 @@ } } } - }, - "put": { + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/publish": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Update a webhook endpoint", - "operationId": "update_1", + "summary": "Publish a draft incident (sets publishedAt, applies component statuses, notifies subscribers)", + "operationId": "publishIncident", "parameters": [ { "name": "id", @@ -23891,17 +24608,25 @@ "type": "string", "format": "uuid" } + }, + { + "name": "incidentId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } } ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" } } - }, - "required": true + } }, "responses": { "200": { @@ -23909,7 +24634,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookEndpointDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -23995,13 +24720,15 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates": { + "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Delete a webhook endpoint", - "operationId": "delete_1", + "summary": "Post an incident timeline update", + "operationId": "postIncidentUpdate", "parameters": [ { "name": "id", @@ -24011,130 +24738,34 @@ "type": "string", "format": "uuid" } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "400": { - "description": "Bad request — the payload failed validation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "401": { - "description": "Unauthorized — missing or invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "403": { - "description": "Forbidden — the actor lacks permission for this resource", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "404": { - "description": "Not found — the requested resource does not exist", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "409": { - "description": "Conflict — the request collides with current resource state", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } }, - "500": { - "description": "Internal server error — see the message field for details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ErrorResponse" - } - } - } - }, - "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", + "name": "incidentId", "in": "path", "required": true, "schema": { "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/CreateStatusPageIncidentUpdateRequest" + } + } + }, + "required": true + }, "responses": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWebhookDeliveryDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24222,13 +24853,13 @@ } } }, - "/api/v1/webhooks/{id}/test": { - "post": { + "/api/v1/status-pages/{id}/incidents/{incidentId}/updates/{updateId}": { + "patch": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Send a test delivery to a webhook endpoint", - "operationId": "test", + "summary": "Edit an existing incident timeline update body", + "operationId": "patchIncidentUpdate", "parameters": [ { "name": "id", @@ -24238,16 +24869,35 @@ "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/TestWebhookEndpointRequest" + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" } } - } + }, + "required": true }, "responses": { "200": { @@ -24255,7 +24905,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookTestResult" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentUpdateDto" } } } @@ -24343,25 +24993,38 @@ } } }, - "/api/v1/webhooks/events": { - "get": { + "/api/v1/status-pages/{id}/layout/reorder": { + "put": { "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": "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": { @@ -24445,20 +25108,56 @@ } } }, - "/api/v1/webhooks/signing-secret": { + "/api/v1/status-pages/{id}/maintenance": { "get": { "tags": [ - "Webhooks" + "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" + } + } ], - "summary": "Get signing secret metadata for the authenticated org", - "operationId": "getSigningSecretInfo", "responses": { "200": { "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWebhookSigningSecretDto" + "$ref": "#/components/schemas/TableValueResultStatusPageIncidentDto" } } } @@ -24544,22 +25243,41 @@ } } } - } - }, - "/api/v1/webhooks/signing-secret/rotate": { + }, "post": { "tags": [ - "Webhooks" + "Status Pages" ], - "summary": "Generate or rotate the organization webhook signing secret", - "operationId": "rotateSigningSecret", + "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": { - "200": { - "description": "OK", + "201": { + "description": "Created", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseString" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24647,20 +25365,30 @@ } } }, - "/api/v1/workspaces": { + "/api/v1/status-pages/{id}/maintenance/{windowId}": { "get": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "List workspaces", - "operationId": "list_1", + "summary": "Get a maintenance window with timeline", + "operationId": "getMaintenance", "parameters": [ { - "name": "pageable", - "in": "query", + "name": "id", + "in": "path", "required": true, "schema": { - "$ref": "#/components/schemas/Pageable" + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], @@ -24670,7 +25398,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/TableValueResultWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24757,29 +25485,49 @@ } } }, - "post": { + "put": { "tags": [ - "Workspaces" + "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" + } + } ], - "summary": "Create workspace", - "operationId": "create_2", "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateWorkspaceRequest" + "$ref": "#/components/schemas/UpdateStatusPageIncidentRequest" } } }, "required": true }, "responses": { - "201": { - "description": "Created", + "200": { + "description": "OK", "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -24865,36 +25613,36 @@ } } } - } - }, - "/api/v1/workspaces/{workspaceId}": { - "get": { + }, + "delete": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Get workspace by ID", - "operationId": "get", + "summary": "Cancel a maintenance window", + "operationId": "deleteMaintenance", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "type": "string", + "format": "uuid" + } + }, + { + "name": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" } } ], "responses": { - "200": { - "description": "OK", - "content": { - "*/*": { - "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" - } - } - } + "204": { + "description": "No Content" }, "400": { "description": "Bad request — the payload failed validation", @@ -24977,21 +25725,146 @@ } } } - }, - "put": { + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/dismiss": { + "post": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Update workspace", - "operationId": "update", + "summary": "Dismiss a draft maintenance window", + "operationId": "dismissMaintenance", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "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" } } ], @@ -24999,11 +25872,10 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateWorkspaceRequest" + "$ref": "#/components/schemas/PublishStatusPageIncidentRequest" } } - }, - "required": true + } }, "responses": { "200": { @@ -25011,7 +25883,7 @@ "content": { "*/*": { "schema": { - "$ref": "#/components/schemas/SingleValueResponseWorkspaceDto" + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" } } } @@ -25097,27 +25969,55 @@ } } } - }, - "delete": { + } + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates": { + "post": { "tags": [ - "Workspaces" + "Status Pages" ], - "summary": "Delete workspace", - "operationId": "delete", + "summary": "Post a maintenance window timeline update", + "operationId": "postMaintenanceUpdate", "parameters": [ { - "name": "workspaceId", + "name": "id", "in": "path", "required": true, "schema": { - "type": "integer", - "format": "int32" + "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": { - "204": { - "description": "No Content" + "201": { + "description": "Created", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/SingleValueResponseStatusPageIncidentDto" + } + } + } }, "400": { "description": "Bad request — the payload failed validation", @@ -25201,209 +26101,3396 @@ } } } - } - }, - "components": { - "schemas": { - "AcknowledgeAllIncidentsResponse": { - "required": [ - "acknowledged", - "skipped" + }, + "/api/v1/status-pages/{id}/maintenance/{windowId}/updates/{updateId}": { + "patch": { + "tags": [ + "Status Pages" ], - "type": "object", - "properties": { - "acknowledged": { - "type": "array", - "description": "Dispatches successfully acknowledged in this request", - "items": { - "$ref": "#/components/schemas/NotificationDispatchDto" + "summary": "Edit an existing maintenance timeline update body", + "operationId": "patchMaintenanceUpdate", + "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": "windowId", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid" + } + }, + { + "name": "updateId", + "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)" + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStatusPageIncidentUpdateRequest" + } + } }, - "ttlMinutes": { - "type": "integer", - "description": "Lock TTL in minutes (default: 30, max: 60)", - "format": "int32", - "nullable": true, - "example": 30 - } + "required": true }, - "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/SingleValueResponseStatusPageIncidentUpdateDto" + } + } + } }, - "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}/notification-deliveries": { + "get": { + "tags": [ + "Status Pages" ], - "type": "object", - "properties": { - "componentId": { - "type": "string", - "description": "Status page component ID", - "format": "uuid" + "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" + } }, - "status": { - "type": "string", - "description": "Component status during this incident", - "enum": [ - "OPERATIONAL", - "DEGRADED_PERFORMANCE", - "PARTIAL_OUTAGE", - "MAJOR_OUTAGE", - "UNDER_MAINTENANCE" + { + "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" ] } }, @@ -26247,6 +30334,42 @@ }, "description": "Result of a bulk monitor action, including partial-success details" }, + "CapturePolicy": { + "type": "object", + "properties": { + "screenshots": { + "type": "string", + "description": "When to capture screenshots", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "trace": { + "type": "string", + "description": "When to capture a Playwright trace", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + }, + "video": { + "type": "string", + "description": "When to capture video", + "nullable": true, + "enum": [ + "always", + "on_failure", + "off" + ] + } + }, + "description": "When to capture screenshots, traces, and video during a code run" + }, "CategoryDto": { "required": [ "category", @@ -27189,7 +31312,7 @@ ] } }, - "description": "Replace all assertions; null preserves current" + "description": "Replace all assertions. Null preserves current" }, "CreateEnvironmentRequest": { "required": [ @@ -27345,7 +31468,6 @@ }, "CreateMonitorRequest": { "required": [ - "config", "name", "type" ], @@ -27372,6 +31494,7 @@ ] }, "config": { + "nullable": true, "oneOf": [ { "$ref": "#/components/schemas/DnsMonitorConfig" @@ -27400,7 +31523,7 @@ "maximum": 86400, "minimum": 10, "type": "integer", - "description": "Check frequency in seconds (10–86400); null defaults to plan minimum (60s on most paid plans)", + "description": "Check frequency in seconds (10–86400). Null defaults to the plan minimum", "format": "int32", "nullable": true }, @@ -27411,16 +31534,16 @@ }, "regions": { "type": "array", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south.", + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south", "nullable": true, "items": { "type": "string", - "description": "Probe regions to run checks from. Allowed values are deployment-dependent; production: us-east, us-west, eu-west, ap-south." + "description": "Probe regions to run checks from. Allowed values are deployment-dependent. Production: us-east, us-west, eu-west, ap-south" } }, "managedBy": { "type": "string", - "description": "Source that created/owns this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API when omitted; set to your surface so audit logs, drift detection, and analytics attribute correctly.", + "description": "Source that created this monitor: DASHBOARD, CLI, TERRAFORM, MCP, or API. Defaults to API", "nullable": true, "enum": [ "DASHBOARD", @@ -27432,7 +31555,7 @@ }, "environmentId": { "type": "string", - "description": "Environment to associate with this monitor", + "description": "Environment to associate with this monitor. Required for browser and multi-step monitors", "format": "uuid", "nullable": true }, @@ -27477,6 +31600,36 @@ "$ref": "#/components/schemas/AddMonitorTagsRequest" } ] + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "maximum": 10, + "minimum": 0, + "type": "integer", + "description": "Fast-retry attempts after failure. Null or 0 disables", + "format": "int32", + "nullable": true + }, + "definitionId": { + "type": "string", + "description": "Existing definition to reuse for a sibling monitor", + "format": "uuid", + "nullable": true + }, + "package": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/MonitorPackageSpec" + } + ] } } }, @@ -27527,6 +31680,20 @@ }, "description": "Request body for creating a notification policy" }, + "CreatePackageUploadRequest": { + "required": [ + "digest" + ], + "type": "object", + "properties": { + "digest": { + "maxLength": 64, + "minLength": 64, + "type": "string", + "description": "SHA-256 hex digest of the package zip to upload (64 chars)" + } + } + }, "CreateResourceGroupRequest": { "required": [ "name" @@ -28219,6 +32386,58 @@ }, "description": "Cursor-paginated response for time-series and append-only data" }, + "CursorPageNotificationDispatchDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/NotificationDispatchDto" + } + }, + "nextCursor": { + "type": "string", + "description": "Opaque cursor for the next page; null when there are no more results", + "nullable": true + }, + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" + } + }, + "description": "Cursor-paginated response for time-series and append-only data" + }, + "CursorPageRunDto": { + "required": [ + "data", + "hasMore" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "description": "Items on this page", + "items": { + "$ref": "#/components/schemas/RunDto" + } + }, + "nextCursor": { + "type": "string", + "description": "Opaque cursor for the next page; null when there are no more results", + "nullable": true + }, + "hasMore": { + "type": "boolean", + "description": "Whether more results exist beyond this page" + } + }, + "description": "Cursor-paginated response for time-series and append-only data" + }, "CursorPageServiceCatalogDto": { "required": [ "data", @@ -28420,6 +32639,108 @@ }, "description": "Incident that overlapped the day" }, + "DefinitionDetailDto": { + "required": [ + "definition", + "heads" + ], + "type": "object", + "properties": { + "definition": { + "$ref": "#/components/schemas/DefinitionDto" + }, + "heads": { + "type": "array", + "description": "Active Heads per environment", + "items": { + "$ref": "#/components/schemas/DefinitionHeadDto" + } + } + }, + "description": "Definition with Heads for each environment" + }, + "DefinitionDto": { + "required": [ + "createdAt", + "id", + "name", + "slug", + "updatedAt", + "organizationId" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Definition identifier", + "format": "uuid" + }, + "organizationId": { + "type": "integer", + "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": "Code-monitor definition" + }, + "DefinitionHeadDto": { + "required": [ + "activatedAt", + "definitionId", + "environment", + "revision" + ], + "type": "object", + "properties": { + "definitionId": { + "type": "string", + "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": "Active Head for a definition in one environment" + }, "DekRotationResultDto": { "required": [ "rotatedAt", @@ -28966,6 +33287,10 @@ ] }, "DnsTtlLowAssertion": { + "required": [ + "type", + "minTtl" + ], "type": "object", "properties": { "type": { @@ -28979,11 +33304,7 @@ "description": "Minimum acceptable TTL in seconds before a warning is raised", "format": "int32" } - }, - "required": [ - "type", - "minTtl" - ] + } }, "DnsTxtContainsAssertion": { "required": [ @@ -29783,6 +34104,10 @@ } }, "IcmpPacketLossAssertion": { + "required": [ + "type", + "maxPercent" + ], "type": "object", "properties": { "type": { @@ -29800,11 +34125,7 @@ "description": "Maximum allowed packet loss percentage before the check fails (0–100)", "format": "double" } - }, - "required": [ - "type", - "maxPercent" - ] + } }, "IcmpReachableAssertion": { "type": "object", @@ -31657,6 +35978,10 @@ } }, "McpMinToolsAssertion": { + "required": [ + "type", + "min" + ], "type": "object", "properties": { "type": { @@ -31670,11 +35995,7 @@ "description": "Minimum number of tools the server must expose", "format": "int32" } - }, - "required": [ - "type", - "min" - ] + } }, "McpProtocolVersionAssertion": { "required": [ @@ -31843,6 +36164,10 @@ } }, "McpToolCountChangedAssertion": { + "required": [ + "type", + "expectedCount" + ], "type": "object", "properties": { "type": { @@ -31856,11 +36181,7 @@ "description": "Expected tool count; warns when the live count differs", "format": "int32" } - }, - "required": [ - "type", - "expectedCount" - ] + } }, "MemberDto": { "required": [ @@ -32236,7 +36557,8 @@ "updatedAt", "organizationId", "frequencySeconds", - "enabled" + "enabled", + "muted" ], "type": "object", "properties": { @@ -32388,7 +36710,7 @@ }, "currentStatus": { "type": "string", - "description": "Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + "description": "Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", "nullable": true, "enum": [ "up", @@ -32397,28 +36719,333 @@ "paused", "unknown" ] + }, + "definitionId": { + "type": "string", + "description": "Definition id for a browser or multi-step monitor. Null on probe monitors", + "format": "uuid", + "nullable": true + }, + "capturePolicy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/CapturePolicy" + } + ] + }, + "fastRetryMaxAttempts": { + "type": "integer", + "description": "Fast-retry max attempts; null/0 = off", + "format": "int32", + "nullable": true + }, + "muted": { + "type": "boolean", + "description": "Whether alert delivery is muted" + }, + "mutedUntil": { + "type": "string", + "description": "Mute expiry; null means indefinite while muted", + "format": "date-time", + "nullable": true + }, + "muteReason": { + "type": "string", + "description": "Optional mute reason", + "nullable": true + }, + "pausedAt": { + "type": "string", + "description": "When the monitor was paused", + "format": "date-time", + "nullable": true + }, + "pauseReason": { + "type": "string", + "description": "Optional pause reason", + "nullable": true + }, + "pauseExpiresAt": { + "type": "string", + "description": "Pause expiry", + "format": "date-time", + "nullable": true + }, + "quarantineOwnerId": { + "type": "string", + "description": "Quarantine person owner id", + "nullable": true + }, + "quarantineUntil": { + "type": "string", + "description": "Quarantine expiry; non-null means quarantined", + "format": "date-time", + "nullable": true + }, + "quarantineReason": { + "type": "string", + "description": "Quarantine reason", + "nullable": true + }, + "upload": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/PackageUploadDto" + } + ] + } + }, + "description": "Full monitor representation" + }, + "MonitorOverlayRequest": { + "type": "object", + "properties": { + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Optional human-readable reason (max 280)", + "nullable": true + }, + "expiresAt": { + "type": "string", + "description": "When this overlay expires", + "format": "date-time", + "nullable": true + } + } + }, + "MonitorPackageSpec": { + "required": [ + "digest", + "entrypoint", + "files" + ], + "type": "object", + "properties": { + "digest": { + "maxLength": 64, + "minLength": 64, + "type": "string", + "description": "SHA-256 hex digest of the package zip (64 characters)" + }, + "entrypoint": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Entrypoint path inside the zip, e.g. tests/login.spec.ts" + }, + "files": { + "maxItems": 256, + "minItems": 0, + "type": "array", + "description": "Relative file paths included in the zip", + "items": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Relative file paths included in the zip" + } + }, + "keys": { + "maxItems": 64, + "minItems": 0, + "type": "array", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears", + "nullable": true, + "items": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Secret names the zip demanded. PUT: null preserves, [] clears" + } + }, + "gitSha": { + "maxLength": 64, + "minLength": 0, + "type": "string", + "description": "Commit SHA from the repo that produced this zip. Client-supplied provenance only", + "nullable": true + }, + "gitMessage": { + "maxLength": 1024, + "minLength": 0, + "type": "string", + "description": "Commit message from the repo that produced this zip", + "nullable": true + }, + "gitFile": { + "maxLength": 512, + "minLength": 0, + "type": "string", + "description": "Path of the declaring file in that repo", + "nullable": true + }, + "authoredBy": { + "maxLength": 255, + "minLength": 0, + "type": "string", + "description": "Author attribution supplied with the package", + "nullable": true + } + }, + "description": "New package zip metadata for this environment" + }, + "MonitorReference": { + "required": [ + "id", + "name" + ], + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Monitor identifier", + "format": "uuid" + }, + "name": { + "type": "string", + "description": "Monitor name" + } + }, + "description": "Monitors that reference this secret for authentication" + }, + "MonitorRunListParams": { + "type": "object", + "properties": { + "phase": { + "type": "string", + "description": "Filter by run phase; omit to return every phase", + "nullable": true + }, + "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 + }, + "q": { + "type": "string", + "description": "Substring match on headline", + "nullable": true + }, + "cursor": { + "type": "string", + "description": "Opaque cursor from a previous page", + "nullable": true + }, + "limit": { + "maximum": 100, + "minimum": 1, + "type": "integer", + "description": "Page size (1–100, default 25)", + "format": "int32" + } + }, + "required": [ + "limit" + ] + }, + "MonitorSecretRequestsDto": { + "required": [ + "environment", + "requests" + ], + "type": "object", + "properties": { + "environment": { + "$ref": "#/components/schemas/EnvironmentDto" + }, + "requests": { + "type": "array", + "description": "Secret keys this monitor requires and their resolve state", + "items": { + "$ref": "#/components/schemas/SecretRequestDto" + } } }, - "description": "Full monitor representation" + "description": "Environment and secret keys this monitor requires" }, - "MonitorReference": { + "MonitorSessionDto": { "required": [ - "id", - "name" + "cookieNames", + "lifecycle", + "reusePolicy", + "setupFile", + "storageKeys" ], "type": "object", "properties": { - "id": { + "lifecycle": { "type": "string", - "description": "Monitor identifier", - "format": "uuid" + "description": "Current session cache state", + "enum": [ + "active", + "expired", + "failed", + "revoked" + ] }, - "name": { + "reusePolicy": { "type": "string", - "description": "Monitor name" + "description": "When the cached session is reused across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "type": "string", + "description": "Setup file path inside the package zip" + }, + "expiresAt": { + "type": "string", + "description": "When the cached session expires", + "format": "date-time", + "nullable": true + }, + "cookieNames": { + "type": "array", + "description": "Cookie names in the cached session", + "items": { + "type": "string", + "description": "Cookie names in the cached session" + } + }, + "storageKeys": { + "type": "array", + "description": "Storage key names in the cached session", + "items": { + "type": "string", + "description": "Storage key names in the cached session" + } + }, + "sizeBytes": { + "type": "integer", + "description": "Cached session size in bytes", + "format": "int32", + "nullable": true + }, + "lastRejectedRunId": { + "type": "string", + "description": "Run that last rejected this cache", + "format": "uuid", + "nullable": true } }, - "description": "Monitors that reference this secret; null on create/update responses" + "description": "Cached sign-in session for a monitor" }, "MonitorsSummaryDto": { "type": "object", @@ -33031,1536 +37658,2464 @@ "format": "date-time", "nullable": true }, - "lastFiredIncidentId": { + "lastFiredIncidentId": { + "type": "string", + "description": "Incident id of the most recent fire in the window; null when none", + "format": "uuid", + "nullable": true + } + }, + "description": "Time-bounded notification policy activity aggregates" + }, + "OfficialSla": { + "type": "object", + "properties": { + "percentage": { + "type": "string", + "description": "Advertised uptime percentage, e.g. '99.99%'", + "nullable": true + }, + "scope": { + "type": "string", + "description": "Scope of the SLA, e.g. 'Monthly uptime per region'", + "nullable": true + }, + "measurement": { + "type": "string", + "description": "How the vendor measures uptime for SLA purposes", + "nullable": true + }, + "exclusions": { + "type": "string", + "description": "Summary of exclusions from SLA calculation", + "nullable": true + }, + "appliesToPlans": { + "type": "array", + "description": "Plan names this SLA applies to, e.g. ['Enterprise']", + "nullable": true, + "items": { + "type": "string", + "description": "Plan names this SLA applies to, e.g. ['Enterprise']" + } + }, + "notCovered": { + "type": "string", + "description": "Services/components NOT covered by the SLA", + "nullable": true + } + }, + "description": "The vendor's officially advertised SLA commitment" + }, + "OpsGenieChannelConfig": { + "required": [ + "channelType", + "apiKey" + ], + "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 + } + } + }, + "OrganizationDto": { + "required": [ + "email", + "name", + "id" + ], + "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 + }, + "websiteUrl": { + "type": "string", + "description": "Organization website URL", + "nullable": true + } + }, + "description": "Organization account details" + }, + "OrgIncidentAnnotationDto": { + "required": [ + "incidentId", + "severity", + "status", + "alerted" + ], + "type": "object", + "properties": { + "incidentId": { + "type": "string", + "description": "Internal org incident ID", + "format": "uuid" + }, + "displayKey": { + "type": "string", + "description": "Human display key (e.g. DEV-42); null until platform INC codes ship", + "nullable": true + }, + "status": { + "type": "string", + "description": "Internal incident lifecycle status", + "enum": [ + "WATCHING", + "TRIGGERED", + "CONFIRMED", + "RESOLVED" + ] + }, + "severity": { + "type": "string", + "description": "Internal incident severity", + "enum": [ + "DOWN", + "DEGRADED", + "MAINTENANCE" + ] + }, + "alerted": { + "type": "boolean", + "description": "Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" + }, + "startedAt": { + "type": "string", + "description": "When the internal incident started", + "format": "date-time", + "nullable": true + } + }, + "description": "Linked internal incident annotation on a vendor status-event row" + }, + "OrgInfo": { + "required": [ + "name", + "id" + ], + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Organization ID", + "format": "int32" + }, + "name": { + "type": "string", + "description": "Organization name" + } + }, + "description": "Organization the key belongs to" + }, + "PackageUploadDto": { + "required": [ + "expiresAt", + "putUrl", + "requiredHeaders" + ], + "type": "object", + "properties": { + "putUrl": { + "minLength": 1, + "type": "string", + "description": "Presigned PUT URL for the zip bytes" + }, + "expiresAt": { + "type": "string", + "description": "When the signed URL expires", + "format": "date-time" + }, + "requiredHeaders": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Must send Content-Type: application/zip and If-None-Match: *" + }, + "description": "Must send Content-Type: application/zip and If-None-Match: *" + } + }, + "description": "Signed package upload target" + }, + "Pageable": { + "type": "object", + "properties": { + "page": { + "minimum": 0, + "type": "integer", + "format": "int32" + }, + "size": { + "minimum": 1, + "type": "integer", + "format": "int32" + }, + "sort": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "page", + "size", + "sort" + ] + }, + "PagerDutyChannelConfig": { + "required": [ + "channelType", + "routingKey" + ], + "type": "object", + "properties": { + "channelType": { + "type": "string", + "enum": [ + "pagerduty" + ] + }, + "routingKey": { + "minLength": 1, + "type": "string", + "description": "PagerDuty Events API v2 routing (integration) key" + }, + "severityOverride": { + "type": "string", + "description": "Override PagerDuty severity mapping", + "nullable": true + } + } + }, + "PageSection": { + "type": "object", + "properties": { + "groupId": { + "type": "string", + "description": "Group ID when this section is a group", + "format": "uuid", + "nullable": true + }, + "componentId": { + "type": "string", + "description": "Component ID when this section is an ungrouped component", + "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": { + "type": "string", + "enum": [ + "phone_call" + ] + }, + "phoneNumber": { + "type": "string", + "description": "Recipient phone number in E.164 format, e.g. +14155550123", + "nullable": true + }, + "verifiedPhoneNumberId": { + "type": "integer", + "description": "Id of an org verified_phone_number row; alternative to phoneNumber", + "format": "int64", + "nullable": true + }, + "phoneNumbers": { + "type": "array", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true, + "items": { + "type": "string", + "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "nullable": true + } + }, + "voiceLanguage": { + "type": "string", + "description": "TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", + "nullable": true + }, + "preferredLanguage": { + "type": "string", + "description": "Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + "nullable": true + } + }, + "required": [ + "channelType" + ] + }, + "PlanInfo": { + "required": [ + "entitlements", + "tier", + "usage", + "trialActive" + ], + "type": "object", + "properties": { + "tier": { + "type": "string", + "description": "Resolved plan tier", + "enum": [ + "FREE", + "STARTER", + "PRO", + "TEAM", + "BUSINESS", + "ENTERPRISE" + ] + }, + "subscriptionStatus": { + "type": "string", + "description": "Subscription status (null if no subscription)", + "nullable": true + }, + "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 + }, + "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": "Hex-encoded SHA-256 of the canonical policy JSON" + }, + "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": "Detection engine version that observed this policy" + }, + "firstSeenAt": { + "type": "string", + "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": "Policy snapshot used during this check (all evaluations of a single check are against one policy)", + "nullable": true + }, + "PollChartBucketDto": { + "required": [ + "bucket", + "totalPolls" + ], + "type": "object", + "properties": { + "bucket": { + "type": "string", + "description": "Start of the time bucket (ISO 8601)", + "format": "date-time" + }, + "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": "Aggregated poll metrics for a time bucket" + }, + "PricingTier": { + "required": [ + "name" + ], + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Tier name, e.g. 'Free', 'Pro', 'Enterprise'" + }, + "slaPercentage": { + "type": "string", + "description": "SLA percentage for this tier, e.g. '99.9%'", + "nullable": true + }, + "priceFrom": { "type": "string", - "description": "Incident id of the most recent fire in the window; null when none", - "format": "uuid", + "description": "Starting price, e.g. '$0', '$25/mo', 'Custom'", "nullable": true } }, - "description": "Time-bounded notification policy activity aggregates" + "description": "Pricing tiers with associated SLA levels" }, - "OfficialSla": { + "PublishRevisionRequest": { + "required": [ + "revisionId" + ], "type": "object", "properties": { - "percentage": { + "revisionId": { "type": "string", - "description": "Advertised uptime percentage, e.g. '99.99%'", + "description": "Existing revision to activate as Head for this monitor's environment", + "format": "uuid" + } + } + }, + "PublishStatusPageIncidentRequest": { + "type": "object", + "properties": { + "title": { + "maxLength": 500, + "minLength": 0, + "type": "string", + "description": "Customer-facing title; null keeps draft value", "nullable": true }, - "scope": { + "impact": { "type": "string", - "description": "Scope of the SLA, e.g. 'Monthly uptime per region'", - "nullable": true + "description": "Impact level; null keeps draft value", + "nullable": true, + "enum": [ + "NONE", + "MINOR", + "MAJOR", + "CRITICAL" + ] }, - "measurement": { + "status": { "type": "string", - "description": "How the vendor measures uptime for SLA purposes", - "nullable": true + "description": "Incident status; null keeps draft value (must be an active status)", + "nullable": true, + "enum": [ + "INVESTIGATING", + "IDENTIFIED", + "MONITORING", + "RESOLVED" + ] }, - "exclusions": { + "body": { "type": "string", - "description": "Summary of exclusions from SLA calculation", + "description": "Initial update body; null keeps draft value", "nullable": true }, - "appliesToPlans": { + "affectedComponents": { "type": "array", - "description": "Plan names this SLA applies to, e.g. ['Enterprise']", + "description": "Affected components; null keeps draft value", "nullable": true, "items": { - "type": "string", - "description": "Plan names this SLA applies to, e.g. ['Enterprise']" + "$ref": "#/components/schemas/AffectedComponent" } }, - "notCovered": { - "type": "string", - "description": "Services/components NOT covered by the SLA", + "notifySubscribers": { + "type": "boolean", + "description": "Whether to notify subscribers (default: true)", "nullable": true } - }, - "description": "The vendor's officially advertised SLA commitment" + } }, - "OpsGenieChannelConfig": { + "PushbulletChannelConfig": { "required": [ "channelType", - "apiKey" + "accessToken" ], "type": "object", "properties": { "channelType": { "type": "string", "enum": [ - "opsgenie" + "pushbullet" ] }, - "apiKey": { + "accessToken": { "minLength": 1, "type": "string", - "description": "OpsGenie API key for alert creation" + "description": "Pushbullet access token" }, - "region": { + "deviceIden": { "type": "string", - "description": "OpsGenie API region: us or eu", + "description": "Target device identifier (broadcasts to all if empty)", "nullable": true } } }, - "OrganizationDto": { + "PushoverChannelConfig": { "required": [ - "email", - "name", - "id" + "channelType", + "userKey", + "appToken" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Unique organization identifier", - "format": "int32" + "channelType": { + "type": "string", + "enum": [ + "pushover" + ] }, - "name": { + "userKey": { + "minLength": 1, "type": "string", - "description": "Organization name" + "description": "Pushover user or group key" }, - "email": { + "appToken": { + "minLength": 1, "type": "string", - "description": "Billing and contact email", - "nullable": true + "description": "Pushover application API token" }, - "size": { + "priority": { "type": "string", - "description": "Team size range (e.g. 1-10, 11-50)", + "description": "Notification priority override (-2 to 2)", "nullable": true }, - "industry": { + "sound": { "type": "string", - "description": "Industry vertical (e.g. SaaS, Fintech)", + "description": "Notification sound override", "nullable": true + } + } + }, + "QuarantineMonitorRequest": { + "required": [ + "expiresAt", + "reason" + ], + "type": "object", + "properties": { + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Reason for this hold (max 280)" }, - "websiteUrl": { + "expiresAt": { "type": "string", - "description": "Organization website URL", - "nullable": true + "description": "When the hold expires", + "format": "date-time" + } + } + }, + "RateLimitInfo": { + "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" + }, + "windowMs": { + "type": "integer", + "description": "Sliding window size in milliseconds", + "format": "int64" } }, - "description": "Organization account details" + "description": "Rate-limit quota for the current sliding window", + "required": [ + "requestsPerMinute", + "remaining", + "windowMs" + ] }, - "OrgIncidentAnnotationDto": { + "RecoveryPolicy": { + "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" + }, + "cooldownMinutes": { + "type": "integer", + "description": "Minutes after resolve before a new incident may open on the same monitor", + "format": "int32" + } + }, + "description": "Auto-recovery settings", "required": [ - "incidentId", - "severity", - "status", - "alerted" + "consecutiveSuccesses", + "minRegionsPassing", + "cooldownMinutes" + ] + }, + "RedirectCountAssertion": { + "required": [ + "type", + "maxCount" ], "type": "object", "properties": { - "incidentId": { + "type": { "type": "string", - "description": "Internal org incident ID", - "format": "uuid" + "enum": [ + "redirect_count" + ] }, - "displayKey": { + "maxCount": { + "type": "integer", + "description": "Maximum number of HTTP redirects allowed before the check fails", + "format": "int32" + } + } + }, + "RedirectTargetAssertion": { + "required": [ + "type", + "expected", + "operator" + ], + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Human display key (e.g. DEV-42); null until platform INC codes ship", - "nullable": true + "enum": [ + "redirect_target" + ] }, - "status": { + "expected": { + "minLength": 1, "type": "string", - "description": "Internal incident lifecycle status", + "description": "Expected final URL after following redirects" + }, + "operator": { + "type": "string", + "description": "Comparison operator (equals, contains, less_than, greater_than, etc.)", "enum": [ - "WATCHING", - "TRIGGERED", - "CONFIRMED", - "RESOLVED" + "equals", + "contains", + "less_than", + "greater_than", + "matches", + "range" ] - }, - "severity": { + } + } + }, + "RegexBodyAssertion": { + "required": [ + "type", + "pattern" + ], + "type": "object", + "properties": { + "type": { "type": "string", - "description": "Internal incident severity", "enum": [ - "DOWN", - "DEGRADED", - "MAINTENANCE" + "regex_body" ] }, - "alerted": { + "pattern": { + "minLength": 1, + "type": "string", + "description": "Regular expression the response body must match" + } + } + }, + "RegionStatusDto": { + "required": [ + "region", + "timestamp", + "passed" + ], + "type": "object", + "properties": { + "region": { + "type": "string", + "description": "Region identifier", + "example": "us-east" + }, + "passed": { "type": "boolean", - "description": "Whether alert channels were eligible to fire (false for AWARENESS silent tracking)" + "description": "Whether the last check in this region passed", + "example": true }, - "startedAt": { + "responseTimeMs": { + "type": "integer", + "description": "Response time in milliseconds for the last check", + "format": "int32", + "nullable": true, + "example": 95 + }, + "timestamp": { "type": "string", - "description": "When the internal incident started", - "format": "date-time", + "description": "Timestamp of the last check in this region (ISO 8601)", + "format": "date-time" + }, + "severityHint": { + "type": "string", + "description": "Severity hint: 'down' for hard failures, 'degraded' for warn-only failures, null when passing", "nullable": true } }, - "description": "Linked internal incident annotation on a vendor status-event row" + "description": "Latest check result for a single region" }, - "OrgInfo": { + "RelatedIncidentsResponse": { "required": [ - "name", - "id" + "data", + "total" ], "type": "object", "properties": { - "id": { - "type": "integer", - "description": "Organization ID", - "format": "int32" + "data": { + "type": "array", + "description": "Related incident rows (newest first, capped by limit)", + "items": { + "$ref": "#/components/schemas/IncidentDto" + } }, - "name": { + "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": "Organization name" + "description": "Secret to attach; null restores name-match", + "format": "uuid", + "nullable": true } }, - "description": "Organization the key belongs to" + "description": "Attach or clear a remapped secret" }, - "Pageable": { + "RemoveMonitorTagsRequest": { + "required": [ + "tagIds" + ], "type": "object", "properties": { - "page": { - "minimum": 0, - "type": "integer", - "format": "int32" - }, - "size": { - "minimum": 1, - "type": "integer", - "format": "int32" - }, - "sort": { + "tagIds": { + "minItems": 1, "type": "array", + "description": "IDs of the tags to detach from the monitor", "items": { - "type": "string" + "type": "string", + "description": "IDs of the tags to detach from the monitor", + "format": "uuid" } } }, + "description": "Request body for removing tags from a monitor" + }, + "ReorderComponentsRequest": { "required": [ - "page", - "size", - "sort" - ] + "positions" + ], + "type": "object", + "properties": { + "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" }, - "PagerDutyChannelConfig": { + "ReorderPageLayoutRequest": { "required": [ - "channelType", - "routingKey" + "sections" ], "type": "object", "properties": { - "channelType": { - "type": "string", - "enum": [ - "pagerduty" - ] - }, - "routingKey": { - "minLength": 1, - "type": "string", - "description": "PagerDuty Events API v2 routing (integration) key" + "sections": { + "minItems": 1, + "type": "array", + "description": "Top-level sections in their new order", + "items": { + "$ref": "#/components/schemas/PageSection" + } }, - "severityOverride": { + "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": "Override PagerDuty severity mapping", + "description": "Optional resolution message or post-mortem notes", "nullable": true } } }, - "PageSection": { + "ResourceGroupDeleteBlockerDto": { + "required": [ + "componentId", + "componentName", + "statusPageId", + "statusPageName", + "statusPageSlug" + ], "type": "object", "properties": { - "groupId": { + "statusPageId": { "type": "string", - "description": "Group ID when this section is a group", - "format": "uuid", - "nullable": true + "description": "Status page that owns the blocking component", + "format": "uuid" + }, + "statusPageName": { + "minLength": 1, + "type": "string", + "description": "Human-readable status page name" + }, + "statusPageSlug": { + "minLength": 1, + "type": "string", + "description": "URL-safe status page slug" }, "componentId": { "type": "string", - "description": "Component ID when this section is an ungrouped component", - "format": "uuid", - "nullable": true + "description": "Blocking GROUP-typed status page component ID", + "format": "uuid" }, - "pageOrder": { - "type": "integer", - "description": "Position on the page (0-based)", - "format": "int32" + "componentName": { + "minLength": 1, + "type": "string", + "description": "Blocking component display name" + }, + "hostname": { + "type": "string", + "description": "Public hostname when a custom domain is configured; null otherwise", + "nullable": true } }, - "description": "A top-level page section (either a group or an ungrouped component)", - "required": [ - "pageOrder" - ] + "description": "Status-page component that references this resource group (blocks delete; public exposure)" }, - "PhoneCallChannelConfig": { + "ResourceGroupDto": { + "required": [ + "createdAt", + "health", + "id", + "name", + "slug", + "updatedAt", + "organizationId", + "suppressMemberAlerts" + ], "type": "object", "properties": { - "channelType": { + "id": { "type": "string", - "enum": [ - "phone_call" - ] + "description": "Unique resource group identifier", + "format": "uuid" }, - "phoneNumber": { + "organizationId": { + "type": "integer", + "description": "Organization this group belongs to", + "format": "int32" + }, + "name": { + "minLength": 1, + "type": "string", + "description": "Human-readable group name" + }, + "slug": { + "minLength": 1, + "type": "string", + "description": "URL-safe group identifier" + }, + "description": { + "type": "string", + "description": "Optional group description", + "nullable": true + }, + "alertPolicyId": { "type": "string", - "description": "Recipient phone number in E.164 format, e.g. +14155550123", + "description": "Notification policy applied to this group", + "format": "uuid", "nullable": true }, - "verifiedPhoneNumberId": { + "defaultFrequency": { "type": "integer", - "description": "Id of an org verified_phone_number row; alternative to phoneNumber", - "format": "int64", + "description": "Default check frequency in seconds for member monitors", + "format": "int32", "nullable": true }, - "phoneNumbers": { + "defaultRegions": { "type": "array", - "description": "Deprecated: use phoneNumber. Accepted as a length-1 list for one release; ignored when phoneNumber or id is set", + "description": "Default regions for member monitors", "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 + "description": "Default regions for member monitors" } }, - "voiceLanguage": { - "type": "string", - "description": "TTS voice language/locale (default: en-US). See VoiceLanguage for supported values", - "nullable": true + "defaultRetryStrategy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/RetryStrategy" + } + ] }, - "preferredLanguage": { + "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": "Preferred language for TTS and notifications (BCP-47, e.g. en-US, de-DE). Alias for voiceLanguage", + "description": "Default environment ID for member monitors", + "format": "uuid", "nullable": true - } - }, - "required": [ - "channelType" - ] - }, - "PlanInfo": { - "required": [ - "entitlements", - "tier", - "usage", - "trialActive" - ], - "type": "object", - "properties": { - "tier": { + }, + "healthThresholdType": { "type": "string", - "description": "Resolved plan tier", + "description": "Health threshold type: COUNT or PERCENTAGE", + "nullable": true, "enum": [ - "FREE", - "STARTER", - "PRO", - "TEAM", - "BUSINESS", - "ENTERPRISE" + "COUNT", + "PERCENTAGE" ] }, - "subscriptionStatus": { - "type": "string", - "description": "Subscription status (null if no subscription)", + "healthThresholdValue": { + "type": "number", + "description": "Health threshold value", "nullable": true }, - "trialActive": { + "suppressMemberAlerts": { "type": "boolean", - "description": "Whether the org is on a trial" + "description": "When true, member-level incidents skip notification dispatch; only group alerts fire" }, - "trialExpiresAt": { - "type": "string", - "description": "Trial expiry (null if not trialing)", - "format": "date-time", + "confirmationDelaySeconds": { + "type": "integer", + "description": "Seconds to wait after health threshold breach before creating group incident", + "format": "int32", "nullable": true }, - "entitlements": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/EntitlementDto" - }, - "description": "Entitlement limits keyed by entitlement name" + "recoveryCooldownMinutes": { + "type": "integer", + "description": "Cooldown minutes after group incident resolves before a new one can open", + "format": "int32", + "nullable": true }, - "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": "Hex-encoded SHA-256 of the canonical policy JSON" + "health": { + "$ref": "#/components/schemas/ResourceGroupHealthDto" }, - "policy": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "Canonical policy document (snake_case, sorted keys)" - }, - "description": "Canonical policy document (snake_case, sorted keys)" + "members": { + "type": "array", + "description": "Member list with individual statuses; populated on detail GET only", + "nullable": true, + "items": { + "$ref": "#/components/schemas/ResourceGroupMemberDto" + } }, - "engineVersion": { - "minLength": 1, + "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": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/IncidentDto" + } + ] + }, + "managedBy": { "type": "string", - "description": "Detection engine version that observed this policy" + "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": [ + "DASHBOARD", + "CLI", + "TERRAFORM", + "MCP", + "API" + ] }, - "firstSeenAt": { + "createdAt": { "type": "string", - "description": "First time the detection engine evaluated against this policy bytes", + "description": "Timestamp when the group was created", "format": "date-time" }, - "lastSeenAt": { + "updatedAt": { "type": "string", - "description": "Most recent time the engine evaluated against this policy bytes", + "description": "Timestamp when the group was last updated", "format": "date-time" } }, - "description": "Policy snapshot used during this check (all evaluations of a single check are against one policy)", - "nullable": true + "description": "Resource group with health summary and optional member details" }, - "PollChartBucketDto": { + "ResourceGroupHealthDto": { "required": [ - "bucket", - "totalPolls" + "status", + "totalMembers", + "operationalCount", + "activeIncidents" ], "type": "object", "properties": { - "bucket": { + "status": { "type": "string", - "description": "Start of the time bucket (ISO 8601)", - "format": "date-time" + "description": "Worst-of health status across all members", + "enum": [ + "operational", + "maintenance", + "degraded", + "down" + ] }, - "uptimePercent": { - "type": "number", - "description": "Uptime percentage for this bucket; null when no data", - "format": "double", - "nullable": true, - "example": 100 + "totalMembers": { + "type": "integer", + "description": "Total number of members in the group", + "format": "int32" }, - "avgResponseTimeMs": { - "type": "number", - "description": "Average response time in milliseconds for this bucket", - "format": "double", + "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": "Computed group health status based on threshold: 'healthy', 'degraded', or 'down'. Null when no health threshold is configured.", "nullable": true, - "example": 245.3 + "enum": [ + "healthy", + "degraded", + "down" + ] }, - "totalPolls": { + "failingCount": { "type": "integer", - "description": "Total polls in this bucket", - "format": "int64", - "example": 60 + "description": "Number of failing members at time of last evaluation; null when no threshold configured", + "format": "int32", + "nullable": true + }, + "healthBreachedSince": { + "type": "string", + "description": "When the health threshold was first breached in the current cycle; null when not breached", + "format": "date-time", + "nullable": true + }, + "healthEvaluatedAt": { + "type": "string", + "description": "When group health was last evaluated (threshold or stamp-only); null until first evaluation", + "format": "date-time", + "nullable": true } }, - "description": "Aggregated poll metrics for a time bucket" + "description": "Aggregated health summary for a resource group" }, - "PricingTier": { + "ResourceGroupMemberDto": { "required": [ - "name" + "createdAt", + "groupId", + "id", + "memberType", + "status" ], "type": "object", "properties": { - "name": { + "id": { "type": "string", - "description": "Tier name, e.g. 'Free', 'Pro', 'Enterprise'" + "description": "Unique group member record identifier", + "format": "uuid" }, - "slaPercentage": { + "groupId": { "type": "string", - "description": "SLA percentage for this tier, e.g. '99.9%'", + "description": "Resource group this member belongs to", + "format": "uuid" + }, + "memberType": { + "type": "string", + "description": "Type of member: 'monitor' or 'service'" + }, + "monitorId": { + "type": "string", + "description": "Monitor ID; set when memberType is 'monitor'", + "format": "uuid", "nullable": true }, - "priceFrom": { + "serviceId": { "type": "string", - "description": "Starting price, e.g. '$0', '$25/mo', 'Custom'", + "description": "Service ID; set when memberType is 'service'", + "format": "uuid", "nullable": true - } - }, - "description": "Pricing tiers with associated SLA levels" - }, - "PublishStatusPageIncidentRequest": { - "type": "object", - "properties": { - "title": { - "maxLength": 500, - "minLength": 0, + }, + "name": { "type": "string", - "description": "Customer-facing title; null keeps draft value", + "description": "Display name of the referenced monitor or service", "nullable": true }, - "impact": { + "slug": { "type": "string", - "description": "Impact level; null keeps draft value", - "nullable": true, - "enum": [ - "NONE", - "MINOR", - "MAJOR", - "CRITICAL" - ] + "description": "Slug identifier for the service (services only); used for icons and uptime API calls", + "nullable": true + }, + "subscriptionId": { + "type": "string", + "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" - } - }, - "description": "Related incidents sharing the same origin within a time window" - }, - "RemoveMonitorTagsRequest": { - "required": [ - "tagIds" - ], - "type": "object", - "properties": { - "tagIds": { - "minItems": 1, + "keys": { "type": "array", - "description": "IDs of the tags to detach from the monitor", + "description": "Secret key names the code demands", "items": { "type": "string", - "description": "IDs of the tags to detach from the monitor", - "format": "uuid" + "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": "Request body for removing tags from a monitor" + "description": "Definition revision package" }, - "ReorderComponentsRequest": { + "RollbackPreviewDto": { "required": [ - "positions" + "affectedMonitors", + "target" ], "type": "object", "properties": { - "positions": { - "minItems": 1, + "target": { + "$ref": "#/components/schemas/RevisionDto" + }, + "current": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/DefinitionHeadDto" + } + ] + }, + "affectedMonitors": { "type": "array", - "description": "Ordered list of component IDs with their new positions", + "description": "Monitors sharing this definition and environment", "items": { - "$ref": "#/components/schemas/ComponentPosition" + "$ref": "#/components/schemas/MonitorDto" } } }, - "description": "Batch component reorder request" + "description": "Consequence preview for rolling back Head in this environment" }, - "ReorderPageLayoutRequest": { + "RollbackRevisionRequest": { "required": [ - "sections" + "reason", + "revisionId" ], "type": "object", "properties": { - "sections": { - "minItems": 1, - "type": "array", - "description": "Top-level sections in their new order", - "items": { - "$ref": "#/components/schemas/PageSection" - } + "revisionId": { + "type": "string", + "description": "Existing revision to restore as Head for this monitor's environment", + "format": "uuid" }, - "groupOrders": { - "type": "array", - "description": "Within-group component ordering; only needed for groups whose internal order changed", - "nullable": true, - "items": { - "$ref": "#/components/schemas/GroupComponentOrder" - } + "reason": { + "maxLength": 280, + "minLength": 0, + "type": "string", + "description": "Why this rollback was performed (1–280 chars)" } - }, - "description": "Reorder page-level layout: groups and ungrouped components share one ordering" + } }, - "ResolveIncidentRequest": { + "RootlyChannelConfig": { + "required": [ + "channelType", + "apiKey" + ], "type": "object", "properties": { - "body": { + "channelType": { "type": "string", - "description": "Optional resolution message or post-mortem notes", + "enum": [ + "rootly" + ] + }, + "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 } } }, - "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, - "type": "string", - "description": "Human-readable group name" - }, - "slug": { - "minLength": 1, - "type": "string", - "description": "URL-safe group identifier" - }, - "description": { + "runId": { "type": "string", - "description": "Optional group description", - "nullable": true + "description": "Run this artifact belongs to", + "format": "uuid" }, - "alertPolicyId": { + "stepId": { "type": "string", - "description": "Notification policy applied to this group", + "description": "Step this screenshot belongs to; null for whole-run kinds", "format": "uuid", "nullable": true }, - "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" - } + "kind": { + "type": "string", + "description": "File kind", + "enum": [ + "screenshot", + "video", + "trace", + "har", + "console", + "runner_log" ] }, - "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": { + "lifecycle": { "type": "string", - "description": "Default environment ID for member monitors", - "format": "uuid", - "nullable": true + "description": "Whether bytes are available, processing, or gone", + "enum": [ + "available", + "processing", + "failed", + "not_captured", + "suppressed", + "never_reached", + "expired", + "no_browser" + ] }, - "healthThresholdType": { + "captureReason": { "type": "string", - "description": "Health threshold type: COUNT or PERCENTAGE", + "description": "Why this file was captured", "nullable": true, "enum": [ - "COUNT", - "PERCENTAGE" + "on_failure", + "named_step", + "customer" ] }, - "healthThresholdValue": { - "type": "number", - "description": "Health threshold value", + "byteSize": { + "type": "integer", + "description": "Stored size in bytes", + "format": "int64", "nullable": true }, - "suppressMemberAlerts": { - "type": "boolean", - "description": "When true, member-level incidents skip notification dispatch; only group alerts fire" - }, - "confirmationDelaySeconds": { - "type": "integer", - "description": "Seconds to wait after health threshold breach before creating group incident", - "format": "int32", + "contentType": { + "type": "string", + "description": "MIME type of the stored file", "nullable": true }, - "recoveryCooldownMinutes": { + "durationMs": { "type": "integer", - "description": "Cooldown minutes after group incident resolves before a new one can open", + "description": "Video duration 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" - } + "viewport": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Screenshot viewport {width,height,dpr}", + "nullable": true + }, + "description": "Screenshot viewport {width,height,dpr}", + "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" - } + "expiresAt": { + "type": "string", + "description": "When stored bytes expire", + "format": "date-time", + "nullable": true }, - "openRegionIncident": { - "nullable": true, - "allOf": [ - { - "$ref": "#/components/schemas/IncidentDto" - } - ] + "expectedByteSize": { + "type": "integer", + "description": "Expected size while a video is encoding", + "format": "int64", + "nullable": true }, - "managedBy": { - "type": "string", - "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": [ - "DASHBOARD", - "CLI", - "TERRAFORM", - "MCP", - "API" - ] + "encodeEtaMs": { + "type": "integer", + "description": "Estimated remaining encode time in milliseconds", + "format": "int32", + "nullable": true }, - "createdAt": { - "type": "string", - "description": "Timestamp when the group was created", - "format": "date-time" + "traceMeta": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Trace summary counts and nearby actions", + "nullable": true + }, + "description": "Trace summary counts and nearby actions", + "nullable": true }, - "updatedAt": { + "createdAt": { "type": "string", - "description": "Timestamp when the group was last updated", + "description": "When this file row was created", "format": "date-time" } }, - "description": "Resource group with health summary and optional member details" + "description": "Run evidence file" }, - "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, - "enum": [ - "healthy", - "degraded", - "down" - ] + "description": "Case title" }, - "failingCount": { - "type": "integer", - "description": "Number of failing members at time of last evaluation; null when no threshold configured", - "format": "int32", + "file": { + "type": "string", + "description": "Spec path inside the package", "nullable": true }, - "healthBreachedSince": { + "status": { "type": "string", - "description": "When the health threshold was first breached in the current cycle; null when not breached", + "description": "Case status", + "enum": [ + "pending", + "running", + "passed", + "failed", + "timed_out", + "skipped", + "interrupted" + ] + }, + "startedAt": { + "type": "string", + "description": "When the case started", "format": "date-time", "nullable": true }, - "healthEvaluatedAt": { + "finishedAt": { "type": "string", - "description": "When group health was last evaluated (threshold or stamp-only); null until first evaluation", + "description": "When the case finished", "format": "date-time", "nullable": true + }, + "durationMs": { + "type": "integer", + "description": "Reporter duration in milliseconds", + "format": "int32", + "nullable": true + }, + "steps": { + "type": "array", + "description": "Steps on this case", + "items": { + "$ref": "#/components/schemas/RunStepDto" + } } }, - "description": "Aggregated health summary for a resource group" + "description": "Run case with nested steps" }, - "ResourceGroupMemberDto": { + "RunCaseListParams": { + "type": "object", + "properties": { + "attempt": { + "type": "integer", + "description": "Only return cases for this Playwright attempt", + "format": "int32", + "nullable": true + } + } + }, + "RunDto": { "required": [ - "createdAt", - "groupId", + "bindingVersionSnapshot", + "bundleDigest", + "capturePolicySnapshot", + "enqueuedAt", "id", - "memberType", - "status" + "monitorId", + "phase", + "region", + "revisionId", + "source", + "organizationId", + "cancelRequested" ], "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": { + "revisionId": { "type": "string", - "description": "Type of member: 'monitor' or 'service'" + "description": "Revision this run executed", + "format": "uuid" }, - "monitorId": { + "region": { + "minLength": 1, "type": "string", - "description": "Monitor ID; set when memberType is 'monitor'", - "format": "uuid", - "nullable": true + "description": "Probe region for this run" }, - "serviceId": { + "source": { "type": "string", - "description": "Service ID; set when memberType is 'service'", - "format": "uuid", - "nullable": true + "description": "What triggered this run", + "enum": [ + "schedule", + "run_now", + "ci", + "fast_retry", + "remote_validation", + "deployment_validation", + "session_renew" + ] }, - "name": { + "enqueuedAt": { "type": "string", - "description": "Display name of the referenced monitor or service", - "nullable": true + "description": "When this run was enqueued", + "format": "date-time" }, - "slug": { + "evaluationCycleId": { "type": "string", - "description": "Slug identifier for the service (services only); used for icons and uptime API calls", + "description": "Evaluation cycle grouping this run with retries", + "format": "uuid", "nullable": true }, - "subscriptionId": { + "retryOfRunId": { "type": "string", - "description": "Subscription ID for the service (services only); used to link to the dependency detail page", + "description": "Parent run when this is a fast retry", "format": "uuid", "nullable": true }, - "status": { + "phase": { "type": "string", - "description": "Computed health status for this member", + "description": "Current run phase", "enum": [ - "operational", - "maintenance", - "degraded", - "down" + "created", + "queued", + "starting", + "running", + "finalizing", + "finished" ] }, - "effectiveFrequency": { - "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", - "nullable": true + "cancelRequested": { + "type": "boolean", + "description": "Whether cancel was requested" }, - "createdAt": { + "outcome": { "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": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", + "description": "Outcome; null until the run is finished", "nullable": true, - "items": { - "type": "number", - "description": "Uptime tick values (0-100) for last-24h mini chart; populated when includeMetrics=true", - "format": "double" - } + "enum": [ + "passed", + "failed", + "execution_error", + "timed_out", + "cancelled", + "inconclusive" + ] }, - "avgLatencyMs": { - "type": "number", - "description": "Average latency in ms (monitors only); populated when includeMetrics=true", - "format": "double", + "headline": { + "type": "string", + "description": "Last control headline", "nullable": true }, - "p95LatencyMs": { - "type": "number", - "description": "P95 latency in ms (monitors only); populated when includeMetrics=true", - "format": "double", + "bundleDigest": { + "minLength": 1, + "type": "string", + "description": "Package digest frozen at create" + }, + "startedAt": { + "type": "string", + "description": "When execution claimed a seat", + "format": "date-time", "nullable": true }, - "lastCheckedAt": { + "finishedAt": { "type": "string", - "description": "Timestamp of the most recent health check; populated when includeMetrics=true", + "description": "When the run finished", "format": "date-time", "nullable": true }, - "monitorType": { + "updatedAt": { "type": "string", - "description": "Monitor type (HTTP, DNS, TCP, ICMP, HEARTBEAT, MCP); monitors only", + "description": "When the run row last changed", + "format": "date-time", "nullable": true }, - "environmentName": { + "lastHeartbeatAt": { "type": "string", - "description": "Environment name; monitors only", + "description": "Last ingest heartbeat", + "format": "date-time", "nullable": true }, - "groupMembershipCount": { - "type": "integer", - "description": "Count of resource groups this monitor or service belongs to; detail GET only — omitted on list", - "format": "int32", + "cancelledBy": { + "type": "string", + "description": "Who requested cancel", "nullable": true }, - "failingSince": { + "artifactsExpiredAt": { "type": "string", - "description": "Start of the current non-operational stretch; null when operational or unknown (services OK); detail GET only — omitted on list", + "description": "When artifact bytes expired", "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 + "capturePolicySnapshot": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Capture settings frozen at create" + }, + "description": "Capture settings frozen at create" }, - "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" - } + "bindingVersionSnapshot": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Resolved secret key names frozen at create" + }, + "description": "Resolved secret key names frozen at create" } }, - "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 - } - }, - "description": "Member incident mark for the trailing 24h uptime strip" - }, - "ResponseSizeAssertion": { - "type": "object", - "properties": { - "type": { + }, + "artifactId": { "type": "string", - "enum": [ - "response_size" - ] + "description": "Artifact this event refers to", + "format": "uuid", + "nullable": true }, - "maxBytes": { - "type": "integer", - "description": "Maximum response body size in bytes before the check fails", - "format": "int32" + "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" } }, - "required": [ - "type", - "maxBytes" - ] + "description": "Run control event" }, - "ResponseTimeAssertion": { + "RunEventParams": { "type": "object", "properties": { - "type": { - "type": "string", - "enum": [ - "response_time" - ] - }, - "thresholdMs": { + "after": { "type": "integer", - "description": "Maximum allowed response time in milliseconds before the check fails", - "format": "int32" + "description": "Replay events with seq greater than this value", + "format": "int64", + "nullable": true } - }, - "required": [ - "type", - "thresholdMs" - ] + } }, - "ResponseTimeWarnAssertion": { + "RunListParams": { "type": "object", "properties": { - "type": { + "phase": { "type": "string", - "enum": [ - "response_time_warn" - ] + "description": "Filter by run phase; omit to return every phase", + "nullable": true }, - "warnMs": { - "type": "integer", - "description": "HTTP response time in milliseconds that triggers a warning only", - "format": "int32" - } - }, - "required": [ - "type", - "warnMs" - ] - }, - "ResultSummaryDto": { - "required": [ - "chartData", - "currentStatus", - "latestPerRegion" - ], - "type": "object", - "properties": { - "currentStatus": { + "outcome": { "type": "string", - "description": "Derived current status across all regions", - "enum": [ - "up", - "degraded", - "down", - "paused", - "unknown" - ] + "description": "Filter by persist outcome; omit to return every outcome", + "nullable": true }, - "latestPerRegion": { - "type": "array", - "description": "Latest check result per region", - "items": { - "$ref": "#/components/schemas/RegionStatusDto" - } + "region": { + "type": "string", + "description": "Filter by probe region", + "nullable": true }, - "chartData": { - "type": "array", - "description": "Time-bucketed chart data for the requested window", - "items": { - "$ref": "#/components/schemas/ChartBucketDto" - } + "source": { + "type": "string", + "description": "Filter by what triggered the run", + "nullable": true }, - "uptime24h": { - "type": "number", - "description": "Uptime percentage over the last 24 hours; null when no data", - "format": "double", - "nullable": true, - "example": 99.95 + "environmentId": { + "type": "string", + "description": "Only return runs whose monitor lives in this environment", + "format": "uuid", + "nullable": true }, - "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" - }, - "RetryStrategy": { - "required": [ - "type", - "maxRetries", - "interval" - ], - "type": "object", - "properties": { - "type": { + "from": { "type": "string", - "description": "Retry strategy kind, e.g. fixed interval between attempts" + "description": "Inclusive lower bound on enqueued_at (default now-30m)", + "format": "date-time", + "nullable": true }, - "maxRetries": { + "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 number of retries after a failed check", + "description": "Page size (1–100, default 50)", "format": "int32" }, - "interval": { + "page": { + "minimum": 0, "type": "integer", - "description": "Delay between retry attempts in seconds", + "description": "Zero-based page index (default 0)", "format": "int32" } }, - "description": "Default retry strategy for member monitors; null clears" - }, - "RootlyChannelConfig": { "required": [ - "channelType", - "apiKey" - ], - "type": "object", - "properties": { - "channelType": { - "type": "string", - "enum": [ - "rootly" - ] - }, - "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 - } - } + "size", + "page" + ] }, - "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)" - }, - "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" + "description": "Step category", + "enum": [ + "named", + "assertion", + "browser_action" + ] }, - "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)" + "status": { + "type": "string", + "description": "Step status", + "enum": [ + "pending", + "running", + "passed", + "slow", + "failed", + "skipped", + "suppressed", + "never_reached" + ] }, - "engineVersion": { - "minLength": 1, + "startedAt": { "type": "string", - "description": "Detection engine version that ran this evaluation" + "description": "When the step started", + "format": "date-time", + "nullable": true }, - "checkId": { + "finishedAt": { "type": "string", - "description": "Scheduler-minted check execution ID (V92) — the causal chain identifier", - "format": "uuid" + "description": "When the step finished", + "format": "date-time", + "nullable": true }, - "triggeringTransitionId": { + "durationMs": { + "type": "integer", + "description": "Reporter duration in milliseconds", + "format": "int32", + "nullable": true + }, + "error": { "type": "string", - "description": "If this evaluation caused a state transition, points to that transition's id", - "format": "uuid", + "description": "Error when the step failed", + "nullable": true + }, + "assertion": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Assertion payload when this step is an assertion", + "nullable": true + }, + "description": "Assertion payload when this step is an assertion", "nullable": true } }, - "description": "All rule evaluations that ran for this check" + "description": "Run step" }, "ScheduledMaintenanceDto": { "required": [ @@ -34642,16 +40197,16 @@ "description": "A scheduled maintenance window from a vendor status page" }, "ScriptMonitorConfig": { - "required": [ - "script" - ], "type": "object", + "additionalProperties": false, "properties": { "script": { "maxLength": 65536, - "minLength": 1, + "minLength": 0, "type": "string", - "description": "Playwright test script source code" + "description": "Legacy inline script on existing rows", + "nullable": true, + "readOnly": true }, "timeoutSeconds": { "maximum": 120, @@ -34663,6 +40218,26 @@ } } }, + "SecretAuditDto": { + "type": "object", + "properties": { + "updatedAt": { + "type": "string", + "description": "When this secret was last updated", + "format": "date-time", + "nullable": true + }, + "updatedBy": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/UserDto" + } + ] + } + }, + "description": "Last update time and author for a secret" + }, "SecretDto": { "required": [ "createdAt", @@ -34704,14 +40279,69 @@ }, "usedByMonitors": { "type": "array", - "description": "Monitors that reference this secret; null on create/update responses", + "description": "Monitors that reference this secret for authentication", "nullable": true, "items": { "$ref": "#/components/schemas/MonitorReference" } } }, - "description": "Secret with change-detection hash; plaintext value is never returned" + "description": "Organization secret and its change-detection hash" + }, + "SecretRequestDto": { + "required": [ + "key", + "readiness" + ], + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Secret key this monitor requires" + }, + "secret": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/SecretDto" + } + ] + }, + "readiness": { + "type": "string", + "description": "Whether this key is resolved or missing", + "enum": [ + "resolved", + "missing" + ] + }, + "fulfilledBy": { + "type": "string", + "description": "Fulfilled from environment variables or a secret", + "nullable": true, + "enum": [ + "env", + "secret" + ] + } + }, + "description": "Secret key a monitor requires and how it is fulfilled" + }, + "SecretUsageDto": { + "required": [ + "monitors" + ], + "type": "object", + "properties": { + "monitors": { + "type": "array", + "description": "Monitors that reference this secret", + "items": { + "$ref": "#/components/schemas/MonitorDto" + } + } + }, + "description": "Monitors that reference this secret" }, "SeoMetadataDto": { "type": "object", @@ -35867,6 +41497,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 +41689,28 @@ } } }, + "SingleValueResponseMonitorSecretRequestsDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSecretRequestsDto" + } + } + }, + "SingleValueResponseMonitorSessionDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/MonitorSessionDto" + } + } + }, "SingleValueResponseMonitorTestResultDto": { "required": [ "data" @@ -36092,6 +41766,17 @@ } } }, + "SingleValueResponsePackageUploadDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/PackageUploadDto" + } + } + }, "SingleValueResponsePolicySnapshotDto": { "required": [ "data" @@ -36147,6 +41832,61 @@ } } }, + "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" + } + } + }, + "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 +41898,17 @@ } } }, + "SingleValueResponseSecretUsageDto": { + "required": [ + "data" + ], + "type": "object", + "properties": { + "data": { + "$ref": "#/components/schemas/SecretUsageDto" + } + } + }, "SingleValueResponseServiceDayDetailDto": { "required": [ "data" @@ -36658,6 +42409,10 @@ } }, "SslExpiryAssertion": { + "required": [ + "type", + "minDaysRemaining" + ], "type": "object", "properties": { "type": { @@ -36671,11 +42426,7 @@ "description": "Minimum days before TLS certificate expiry; fails or warns below this threshold", "format": "int32" } - }, - "required": [ - "type", - "minDaysRemaining" - ] + } }, "StateTransitionDetails": { "required": [ @@ -37822,10 +43573,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37858,10 +43605,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37894,10 +43637,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37930,10 +43669,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -37966,10 +43701,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38002,9 +43733,37 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultDefinitionDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DefinitionDto" + } }, - "nextCursor": { - "type": "string", + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } @@ -38038,10 +43797,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38074,10 +43829,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38110,10 +43861,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38146,10 +43893,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38182,10 +43925,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38218,10 +43957,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38254,10 +43989,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38290,10 +44021,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38326,10 +44053,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38362,10 +44085,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38398,10 +44117,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38434,10 +44149,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38470,10 +44181,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38506,9 +44213,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 +44277,42 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultRunArtifactDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RunArtifactDto" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true }, - "nextCursor": { - "type": "string", + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } }, - "TableValueResultScheduledMaintenanceDto": { + "TableValueResultRunCaseDto": { "required": [ "data", "hasNext", @@ -38560,7 +44323,39 @@ "data": { "type": "array", "items": { - "$ref": "#/components/schemas/ScheduledMaintenanceDto" + "$ref": "#/components/schemas/RunCaseDto" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true + }, + "totalPages": { + "type": "integer", + "format": "int32", + "nullable": true + } + } + }, + "TableValueResultRunDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RunDto" } }, "hasNext": { @@ -38578,9 +44373,37 @@ "type": "integer", "format": "int32", "nullable": true + } + } + }, + "TableValueResultScheduledMaintenanceDto": { + "required": [ + "data", + "hasNext", + "hasPrev" + ], + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ScheduledMaintenanceDto" + } + }, + "hasNext": { + "type": "boolean" + }, + "hasPrev": { + "type": "boolean" + }, + "totalElements": { + "type": "integer", + "format": "int64", + "nullable": true }, - "nextCursor": { - "type": "string", + "totalPages": { + "type": "integer", + "format": "int32", "nullable": true } } @@ -38614,10 +44437,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38650,10 +44469,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38686,10 +44501,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38722,10 +44533,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38758,10 +44565,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38794,10 +44597,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38830,10 +44629,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38866,10 +44661,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38902,10 +44693,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38938,10 +44725,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -38974,10 +44757,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39010,10 +44789,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39046,10 +44821,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39082,10 +44853,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39118,10 +44885,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39154,10 +44917,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -39190,10 +44949,6 @@ "type": "integer", "format": "int32", "nullable": true - }, - "nextCursor": { - "type": "string", - "nullable": true } } }, @@ -40474,7 +46229,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 +46262,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 +46294,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 +46305,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 +46334,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 +46349,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 +47292,35 @@ "channelType" ] }, + "UpsertMonitorSessionRequest": { + "required": [ + "reusePolicy", + "setupFile" + ], + "type": "object", + "properties": { + "reusePolicy": { + "type": "string", + "description": "When to reuse the cached session across runs", + "enum": [ + "reuse", + "every_run", + "on_failure" + ] + }, + "setupFile": { + "minLength": 1, + "type": "string", + "description": "Setup file path inside the package zip" + }, + "expiresAt": { + "type": "string", + "description": "When the cached session expires", + "format": "date-time", + "nullable": true + } + } + }, "UptimeBucketDto": { "required": [ "timestamp", @@ -41594,6 +47407,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 +47785,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..590946a 100644 --- a/src/devhelm/_generated.py +++ b/src/devhelm/_generated.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Annotated, Any, Literal -from pydantic import ConfigDict, AwareDatetime, BaseModel, EmailStr, Field, RootModel +from pydantic import AwareDatetime, BaseModel, ConfigDict, EmailStr, Field, RootModel from enum import StrEnum from uuid import UUID from datetime import date as date_aliased @@ -538,6 +538,35 @@ class Action(StrEnum): remove_tag = "REMOVE_TAG" +class Screenshots(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Trace(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class Video(StrEnum): + always = "always" + on_failure = "on_failure" + off = "off" + + +class CapturePolicy(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + screenshots: Annotated[ + Screenshots | None, Field(description="When to capture screenshots") + ] = None + trace: Annotated[ + Trace | None, Field(description="When to capture a Playwright trace") + ] = None + video: Annotated[Video | None, Field(description="When to capture video")] = None + + class CategoryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) category: Annotated[ @@ -989,6 +1018,18 @@ class Type(StrEnum): multi_step_api = "MULTI_STEP_API" +class CreatePackageUploadRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip to upload (64 chars)", + max_length=64, + min_length=64, + ), + ] + + class HealthThresholdType(StrEnum): count = "COUNT" # type: ignore[assignment] percentage = "PERCENTAGE" @@ -1387,6 +1428,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 +3303,183 @@ class MonitorAuthDto(BaseModel): config: ApiKeyAuthConfig | BasicAuthConfig | BearerAuthConfig | HeaderAuthConfig +class MonitorOverlayRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str | None, + Field( + description="Optional human-readable reason (max 280)", + max_length=280, + min_length=0, + ), + ] = None + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When this overlay expires"), + ] = None + + +class File(RootModel[str]): + root: Annotated[ + str, + Field( + description="Relative file paths included in the zip", + max_length=512, + min_length=0, + ), + ] + + +class Key(RootModel[str]): + root: Annotated[ + str, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=255, + min_length=0, + ), + ] + + +class MonitorPackageSpec(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + digest: Annotated[ + str, + Field( + description="SHA-256 hex digest of the package zip (64 characters)", + max_length=64, + min_length=64, + ), + ] + entrypoint: Annotated[ + str, + Field( + description="Entrypoint path inside the zip, e.g. tests/login.spec.ts", + max_length=512, + min_length=0, + ), + ] + files: Annotated[ + list[File], + Field( + description="Relative file paths included in the zip", + max_length=256, + min_length=0, + ), + ] + keys: Annotated[ + list[Key] | None, + Field( + description="Secret names the zip demanded. PUT: null preserves, [] clears", + max_length=64, + min_length=0, + ), + ] = None + git_sha: Annotated[ + str | None, + Field( + alias="gitSha", + description="Commit SHA from the repo that produced this zip. Client-supplied provenance only", + max_length=64, + min_length=0, + ), + ] = None + git_message: Annotated[ + str | None, + Field( + alias="gitMessage", + description="Commit message from the repo that produced this zip", + max_length=1024, + min_length=0, + ), + ] = None + git_file: Annotated[ + str | None, + Field( + alias="gitFile", + description="Path of the declaring file in that repo", + max_length=512, + min_length=0, + ), + ] = None + authored_by: Annotated[ + str | None, + Field( + alias="authoredBy", + description="Author attribution supplied with the package", + max_length=255, + min_length=0, + ), + ] = None + + class MonitorReference(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Monitor identifier")] name: Annotated[str, Field(description="Monitor name")] +class 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 + 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"), + ] + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When the cached session expires"), + ] = None + cookie_names: Annotated[ + list[str], + Field(alias="cookieNames", description="Cookie names in the cached session"), + ] + storage_keys: Annotated[ + list[str], + Field( + alias="storageKeys", description="Storage key names in the cached session" + ), + ] + size_bytes: Annotated[ + int | None, Field(alias="sizeBytes", description="Cached session size in bytes") + ] = None + last_rejected_run_id: Annotated[ + UUID | None, + Field( + alias="lastRejectedRunId", description="Run that last rejected this cache" + ), + ] = None + + class MonitorsSummaryDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) total: Annotated[ @@ -3634,6 +3871,29 @@ class OrgInfo(BaseModel): name: Annotated[str, Field(description="Organization name")] +class PackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + put_url: Annotated[ + str, + Field( + alias="putUrl", + description="Presigned PUT URL for the zip bytes", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime, + Field(alias="expiresAt", description="When the signed URL expires"), + ] + required_headers: Annotated[ + dict[str, str], + Field( + alias="requiredHeaders", + description="Must send Content-Type: application/zip and If-None-Match: *", + ), + ] + + class Pageable(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) page: Annotated[int, Field(ge=0)] @@ -3848,6 +4108,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 +4205,19 @@ class PushoverChannelConfig(BaseModel): ) +class QuarantineMonitorRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reason: Annotated[ + str, + Field( + description="Reason for this hold (max 280)", max_length=280, min_length=0 + ), + ] + expires_at: Annotated[ + AwareDatetime, Field(alias="expiresAt", description="When the hold expires") + ] + + class RateLimitInfo(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) requests_per_minute: Annotated[ @@ -4043,6 +4327,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 +4595,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" @@ -4410,6 +4781,284 @@ class RuleEvaluationDto(BaseModel): ] = None +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: Annotated[ + dict[str, dict[str, Any]] | None, + Field(description="Screenshot viewport {width,height,dpr}"), + ] = 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[ + dict[str, dict[str, Any]] | None, + Field(alias="traceMeta", description="Trace summary counts and nearby actions"), + ] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="When this file row was created"), + ] + + +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 + + +class RunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + 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, Field(alias="monitorId", description="Monitor this run belongs to") + ] + 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( + alias="evaluationCycleId", + description="Evaluation cycle grouping this run with retries", + ), + ] = None + retry_of_run_id: Annotated[ + UUID | None, + Field(alias="retryOfRunId", description="Parent run when this is a fast retry"), + ] = 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 + bundle_digest: Annotated[ + str, + Field( + alias="bundleDigest", + description="Package digest frozen at create", + min_length=1, + ), + ] + started_at: Annotated[ + AwareDatetime | None, + Field(alias="startedAt", description="When execution claimed a seat"), + ] = None + finished_at: Annotated[ + AwareDatetime | None, + Field(alias="finishedAt", description="When the run finished"), + ] = None + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When the run row last changed"), + ] = None + last_heartbeat_at: Annotated[ + AwareDatetime | None, + Field(alias="lastHeartbeatAt", description="Last ingest heartbeat"), + ] = None + 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="capturePolicySnapshot", + description="Capture settings frozen at create", + ), + ] + binding_version_snapshot: Annotated[ + dict[str, dict[str, Any]], + Field( + alias="bindingVersionSnapshot", + description="Resolved secret key names frozen at create", + ), + ] + + +class RunEventDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[UUID, Field(description="Event identifier")] + organization_id: Annotated[ + int, + Field(alias="organizationId", description="Organization this event belongs to"), + ] + 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 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 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 ScheduledMaintenanceDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: Annotated[UUID, Field(description="Unique maintenance record identifier")] @@ -4475,13 +5124,13 @@ class ScheduledMaintenanceDto(BaseModel): class ScriptMonitorConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) script: Annotated[ - str, + str | None, Field( - description="Playwright test script source code", + description="Legacy inline script on existing rows", max_length=65536, - min_length=1, + min_length=0, ), - ] + ] = None timeout_seconds: Annotated[ int | None, Field( @@ -4522,11 +5171,27 @@ class SecretDto(BaseModel): alias="updatedAt", description="Timestamp when the secret was last updated" ), ] - used_by_monitors: Annotated[ - list[MonitorReference] | None, + used_by_monitors: Annotated[ + list[MonitorReference] | None, + Field( + alias="usedByMonitors", + 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="usedByMonitors", - description="Monitors that reference this secret; null on create/update responses", + alias="fulfilledBy", + description="Fulfilled from environment variables or a secret", ), ] = None @@ -5084,6 +5749,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 +5769,11 @@ class SingleValueResponseOrganizationDto(BaseModel): data: OrganizationDto +class SingleValueResponsePackageUploadDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: PackageUploadDto + + class SingleValueResponsePolicySnapshotDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: PolicySnapshotDto @@ -5114,6 +5789,16 @@ class SingleValueResponseResultSummaryDto(BaseModel): data: ResultSummaryDto +class SingleValueResponseRevisionDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RevisionDto + + +class SingleValueResponseRunDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: RunDto + + class SingleValueResponseSecretDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: SecretDto @@ -5766,7 +6451,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 +6460,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 +6469,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 +6478,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 +6496,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 +6505,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 +6514,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 +6523,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 +6532,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 +6541,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 +6550,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 +6568,24 @@ 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 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 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 TableValueResultScheduledMaintenanceDto(BaseModel): @@ -5886,7 +6595,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 +6604,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 +6613,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 +6622,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 +6631,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 +6640,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 +6649,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 +6658,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 +6667,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 +6676,6 @@ class TableValueResultStatusPageSubscriberDto(BaseModel): has_prev: Annotated[bool, Field(alias="hasPrev")] total_elements: Annotated[int | None, Field(alias="totalElements")] = None total_pages: Annotated[int | None, Field(alias="totalPages")] = None - next_cursor: Annotated[str | None, Field(alias="nextCursor")] = None class TagDto(BaseModel): @@ -7400,6 +8099,35 @@ class UpdateZapierChannelConfig(BaseModel): ] = None +class ReusePolicy(StrEnum): + reuse = "reuse" + every_run = "every_run" + on_failure = "on_failure" + + +class UpsertMonitorSessionRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + reuse_policy: Annotated[ + ReusePolicy, + Field( + alias="reusePolicy", + description="When to reuse the cached session across runs", + ), + ] + setup_file: Annotated[ + str, + Field( + alias="setupFile", + description="Setup file path inside the package zip", + min_length=1, + ), + ] + expires_at: Annotated[ + AwareDatetime | None, + Field(alias="expiresAt", description="When the cached session expires"), + ] = None + + class UptimeBucketDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) timestamp: Annotated[ @@ -7487,6 +8215,46 @@ class UptimeDto(BaseModel): ] +class UserDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + id: Annotated[int, Field(description="Unique user identifier")] + email: Annotated[str, Field(description="User email address")] + email_verified: Annotated[ + bool, + Field( + alias="emailVerified", + description="Whether the email address has been verified", + ), + ] + name: Annotated[str | None, Field(description="Display name; null if not set")] = ( + None + ) + user_role: Annotated[ + str, Field(alias="userRole", description="Platform role: USER or SUPERADMIN") + ] + onboarding_stage: Annotated[ + str | None, + Field( + alias="onboardingStage", + description="Current onboarding progress stage; null when completed", + ), + ] = None + image_url: Annotated[ + str | None, + Field(alias="imageUrl", description="Profile image URL; null if not set"), + ] = None + created_at: Annotated[ + AwareDatetime, + Field(alias="createdAt", description="Timestamp when the account was created"), + ] + updated_at: Annotated[ + AwareDatetime, + Field( + alias="updatedAt", description="Timestamp when the account was last updated" + ), + ] + + class VoiceLanguageDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) code: Annotated[ @@ -7654,6 +8422,16 @@ class WorkspaceDto(BaseModel): ] +class WriteSecretEnvironmentValueRequest(BaseModel): + model_config = ConfigDict(extra="forbid", populate_by_name=True) + value: Annotated[ + str, + Field( + description="Plaintext value to encrypt for this environment", min_length=1 + ), + ] + + class ZapierChannelConfig(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) channel_type: Annotated[Literal["zapier"], Field(alias="channelType")] = "zapier" @@ -7952,12 +8730,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 +8747,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 +8780,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 +8989,44 @@ class CreditPolicy(BaseModel): ] = None +class CursorPageNotificationDispatchDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: Annotated[ + list[NotificationDispatchDto], Field(description="Items on this page") + ] + next_cursor: Annotated[ + str | None, + Field( + alias="nextCursor", + description="Opaque cursor for the next page; null when there are no more results", + ), + ] = None + has_more: Annotated[ + bool, + Field( + alias="hasMore", description="Whether more results exist beyond this page" + ), + ] + + +class 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" + ), + ] + + class CursorPageServiceCatalogDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: Annotated[list[ServiceCatalogDto], Field(description="Items on this page")] @@ -8252,6 +9087,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 +9777,69 @@ class MonitorDto(BaseModel): str | None, Field( alias="currentStatus", - description="Current operational state — UP, DOWN, DEGRADED, PAUSED, or UNKNOWN if no probe data yet", + description="Current operational state. One of UP, DOWN, DEGRADED, PAUSED, or UNKNOWN", + ), + ] = None + definition_id: Annotated[ + UUID | None, + Field( + alias="definitionId", + description="Definition id for a browser or multi-step monitor. Null on probe monitors", + ), + ] = None + capture_policy: Annotated[CapturePolicy | None, Field(alias="capturePolicy")] = None + fast_retry_max_attempts: Annotated[ + int | None, + Field( + alias="fastRetryMaxAttempts", + description="Fast-retry max attempts; null/0 = off", + ), + ] = None + muted: Annotated[bool, Field(description="Whether alert delivery is muted")] + muted_until: Annotated[ + AwareDatetime | None, + Field( + alias="mutedUntil", + description="Mute expiry; null means indefinite while muted", + ), + ] = None + mute_reason: Annotated[ + str | None, Field(alias="muteReason", description="Optional mute reason") + ] = None + paused_at: Annotated[ + AwareDatetime | None, + Field(alias="pausedAt", description="When the monitor was paused"), + ] = None + pause_reason: Annotated[ + str | None, Field(alias="pauseReason", description="Optional pause reason") + ] = None + pause_expires_at: Annotated[ + AwareDatetime | None, Field(alias="pauseExpiresAt", description="Pause expiry") + ] = None + quarantine_owner_id: Annotated[ + str | None, + Field(alias="quarantineOwnerId", description="Quarantine person owner id"), + ] = None + quarantine_until: Annotated[ + AwareDatetime | None, + Field( + alias="quarantineUntil", + description="Quarantine expiry; non-null means quarantined", ), ] = None + quarantine_reason: Annotated[ + str | None, Field(alias="quarantineReason", description="Quarantine reason") + ] = None + upload: PackageUploadDto | None = None + + +class MonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + environment: EnvironmentDto + requests: Annotated[ + list[SecretRequestDto], + Field(description="Secret keys this monitor requires and their resolve state"), + ] class MonitorTestRequest(BaseModel): @@ -9180,6 +10095,77 @@ class ResourceGroupMemberDto(BaseModel): ] = 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 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 SecretAuditDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + updated_at: Annotated[ + AwareDatetime | None, + Field(alias="updatedAt", description="When this secret was last updated"), + ] = None + updated_by: Annotated[UserDto | None, Field(alias="updatedBy")] = None + + +class SecretUsageDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + monitors: Annotated[ + list[MonitorDto], Field(description="Monitors that reference this secret") + ] + + class ServiceIncidentDetailDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) id: UUID @@ -9244,6 +10230,11 @@ class SingleValueResponseDashboardOverviewDto(BaseModel): 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,6 +10260,11 @@ class SingleValueResponseMonitorDto(BaseModel): data: MonitorDto +class SingleValueResponseMonitorSecretRequestsDto(BaseModel): + model_config = ConfigDict(extra="ignore", populate_by_name=True) + data: MonitorSecretRequestsDto + + class SingleValueResponseMonitorVersionDto(BaseModel): model_config = ConfigDict(extra="ignore", populate_by_name=True) data: MonitorVersionDto @@ -9284,6 +10280,26 @@ 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 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 +10519,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 +10528,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 +10537,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 +10546,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 +10555,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 +10564,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 +10573,15 @@ 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 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 TableValueResultStatusPageDto(BaseModel): @@ -9573,7 +10591,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 +10600,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 +10609,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 +10618,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 +10627,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 +10636,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 +10645,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 +10654,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 +10740,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 +10759,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 +10798,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 +10812,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): @@ -9990,6 +11015,14 @@ class CursorPageIncidentActivityEventDto(BaseModel): ] +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): model_config = ConfigDict(extra="ignore", populate_by_name=True) incident: IncidentDto @@ -10177,6 +11210,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 +11252,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 +11261,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):