{
  "openapi": "3.1.0",
  "info": {
    "title": "Visual Sentinel API",
    "description": "Website monitoring API with six layers: uptime, performance, SSL, DNS, visual change detection and content change detection.\n\n## Authentication\n\nEndpoints accept either of two credentials unless an operation says otherwise.\n\n### 1. Session cookie (web clients)\nCall `POST /api/auth/login` with email and password to get a session cookie. The cookie is sent automatically with later requests. Session writes are CSRF protected (send `X-CSRF-Token` on POST, PUT, PATCH and DELETE).\n\n### 2. API key (agents, integrations, scripts)\nOwners and admins create keys in **Organization settings > Developer**. A key is `vs_` followed by 64 hexadecimal characters and is shown once. Send it as any of:\n- `Authorization: Bearer vs_...` header (recommended)\n- `X-API-Key: vs_...` header\n- `?api_key=vs_...` query parameter\n\n**API access comes with every paid plan** (Solo, Starter, Business, Agency and custom Enterprise plans). On a plan without it (Free) every key request returns 403 with code `API_ACCESS_NOT_IN_PLAN`.\n\nScopes have the form `{resource}:{read|write}`:\n- GET requests need `{resource}:read`. POST, PUT, PATCH and DELETE need `{resource}:write`. In the dashboard, choosing write also grants read.\n- `{resource}:*` grants read and write on one resource. `*` grants every resource.\n- A missing scope returns 403 with code `SCOPE_DENIED` and names the scope the request needs.\n- Platform admin endpoints under `/api/admin/*` are blocked for API keys whatever the scope.\n- CSRF checks are skipped for API key requests.\n- The role of the member who created the key applies, so a key made by a viewer cannot write.\n\nResources and the paths they cover:\n- `monitors`: `/api/monitors/*`, `/api/monitoring/*`, `/api/metrics/*`, `/api/dependencies/*`, `/api/reports/*`, `/api/dns/*`\n- `incidents`: `/api/incidents/*`\n- `servers`: `/api/servers/*` (the dashboard grants read only)\n- `status-pages`: `/api/status-pages/*`\n- `alerts`: `/api/alerts/*`, `/api/alert-rules/*`, `/api/alert-groups/*`\n- `channels`: `/api/notification-channels/*`, `/api/notifications/*`\n- `maintenance`: `/api/maintenance/*`\n- `organization`: `/api/organization/*`, `/api/settings/*`, `/api/plan`, `/api/integrations/*`\n- `user`: `/api/user/*`, `/api/profile/*`, `/api/onboarding/*`\n\nOther paths, for example `/api/overview`, `/api/workspace/*`, `/api/insights/*`, `/api/analytics/*` and `/api/billing/*`, resolve to the `general` resource and need a key with the `*` scope. The dashboard does not create `*` keys.\n\n### Session-only endpoints (cookie required)\nThese endpoints stay session-only by design. An API key on them returns 403 with code `SESSION_REQUIRED` (or 401 where no session exists):\n- `/api/auth/*` (login, logout, refresh, 2FA, password reset, OAuth)\n- `/api/billing/checkout`, `/api/billing/change-plan`, `/api/billing/portal` (billing changes)\n- `DELETE /api/organization`, member and invitation management under `/api/organization/members` and `/api/organization/invitations`, `POST/PUT/DELETE /api/organization/smtp`, `POST /api/organization/leave`, and `POST/PATCH/DELETE /api/api-keys` (account and access management)\n- `/api/integrations/slack/auth` (OAuth start)\n- `/api/organization/invitations/accept` (email link flow)\n- `/api/user/delete-account`\n- `/api/user/organizations/switch` (changes the session cookie)\n- `/api/chat/*`, `/api/ai/*`, `/api/incidents/{id}/summarize`, `/api/alert-groups/{id}/summarize`, `/api/reports/digest`, `POST /api/monitors/{id}/anomalies`, `POST /api/monitors/{id}/report` (AI and reporting features)\n\n## Check regions\n\nUptime checks for HTTP, HTTPS, KEYWORD, API and GRAPHQL monitors can run from `EU` (Europe), `US` (United States) and `ASIA` (Asia Pacific); other monitor types run from `EU`. Set them with `locations` on monitor create and update. Screenshots for visual checks are taken in `EU` or `ASIA` (`visualRegion`).\n\nAsia Pacific is enabled per workspace during its rollout. `GET /api/monitoring/regions` reports whether this workspace can use it. When it cannot, monitor create and update with `ASIA` return 400 with code `REGION_UNAVAILABLE`. A region outside your plan returns 403 with code `LOCATION_RESTRICTED`.\n\n## Mobile apps (iOS, Android, Mac)\n\nNative apps can use the same login flow: `POST /api/auth/login` returns a JWT. Send it as `Authorization: Bearer <jwt>` on every later request. CSRF is skipped for Bearer tokens. Refresh tokens with `POST /api/auth/refresh`, passing the refresh token in the request body (or the `X-Client-Type: mobile` header).\n\n## Rate limits\n\n- API keys: 1,000 requests per minute per key. Over the limit the API returns 429 with code `RATE_LIMIT` and a `Retry-After` header.\n- Login: 15 attempts per 5 minutes\n- Registration: 10 per hour and 30 per day per network address\n- Monitor creation: 1,000 per hour per workspace\n- Alert rule creation: 20 per minute\n- Bulk monitor changes (`/api/monitors/bulk-*`): 30 per minute per workspace\n- Public tools (`/api/tools/*`): 10 per minute per IP address\n\n## Base URL\n\nProduction: `https://visualsentinel.com`",
    "version": "2.225.0",
    "contact": {
      "name": "Visual Sentinel Support",
      "url": "https://visualsentinel.com/contact",
      "email": "support@visualsentinel.com"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://visualsentinel.com/terms"
    }
  },
  "servers": [
    {
      "url": "https://visualsentinel.com",
      "description": "Production server"
    }
  ],
  "tags": [
    {
      "name": "System",
      "description": "Health checks, metrics, and system status"
    },
    {
      "name": "Authentication",
      "description": "User authentication, sessions, OAuth, and 2FA"
    },
    {
      "name": "Monitors",
      "description": "Website and endpoint monitoring CRUD and operations"
    },
    {
      "name": "Visual Monitoring",
      "description": "Screenshot-based visual regression detection"
    },
    {
      "name": "Servers",
      "description": "Server infrastructure monitoring via agent"
    },
    {
      "name": "Server Alerts",
      "description": "Server alert history and configuration"
    },
    {
      "name": "Notification Channels",
      "description": "Manage notification destinations (email, Slack, Discord, etc.)"
    },
    {
      "name": "Alerts",
      "description": "Alert management, acknowledgment, and resolution"
    },
    {
      "name": "Alert Rules",
      "description": "Configure alerting conditions and thresholds"
    },
    {
      "name": "Alert Groups",
      "description": "Grouped alert management"
    },
    {
      "name": "Incidents",
      "description": "Incident tracking and management"
    },
    {
      "name": "Status Pages",
      "description": "Public status page management"
    },
    {
      "name": "Teams",
      "description": "Team management and member assignment"
    },
    {
      "name": "Organization",
      "description": "Organization settings, members, invitations, and branding"
    },
    {
      "name": "Maintenance",
      "description": "Scheduled maintenance windows"
    },
    {
      "name": "Billing",
      "description": "Subscription management and checkout"
    },
    {
      "name": "Integrations",
      "description": "Third-party integrations (Slack, Discord, PagerDuty, webhooks, Google)"
    },
    {
      "name": "Tools",
      "description": "Free public website checking tools"
    },
    {
      "name": "Reports",
      "description": "Report generation and digest emails. Workspace digest email AI summaries are optional, off by default, and added only when sending an opted-in digest on an eligible plan."
    },
    {
      "name": "Analytics",
      "description": "Analytics, journeys, and subscription events"
    },
    {
      "name": "Notifications",
      "description": "In-app notification management"
    },
    {
      "name": "User",
      "description": "User profile and preferences"
    },
    {
      "name": "Chat",
      "description": "AI chat support system"
    },
    {
      "name": "Onboarding",
      "description": "User onboarding flow"
    },
    {
      "name": "Settings",
      "description": "Application settings (deduplication, reports)"
    },
    {
      "name": "Public",
      "description": "Unauthenticated public endpoints (blog, status pages, stats)"
    },
    {
      "name": "Webhooks",
      "description": "Incoming webhook handlers (Paddle, WhatsApp)"
    },
    {
      "name": "API Keys",
      "description": "API key management"
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Health check",
        "description": "Returns system health status including database, cache, and worker connectivity.",
        "operationId": "getHealth",
        "security": [],
        "responses": {
          "200": {
            "description": "System healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/metrics": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Prometheus metrics",
        "description": "Get metrics in Prometheus format for external monitoring systems. Each API key can call this 12 times per minute, so use a scrape interval of 15 seconds or longer. Values can be up to 15 seconds old.",
        "operationId": "getMetrics",
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Prometheus metrics",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing API key"
          },
          "403": {
            "description": "The key lacks the monitors:read scope, or the plan does not include API access"
          },
          "429": {
            "description": "More than 12 requests in a minute for this API key. See the Retry-After header."
          }
        }
      }
    },
    "/api/plan": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Get current plan details",
        "description": "Returns the current organization's plan, limits, and usage.",
        "operationId": "getPlan",
        "responses": {
          "200": {
            "description": "Plan details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "plan": {
                      "type": "string"
                    },
                    "limits": {
                      "type": "object"
                    },
                    "usage": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/dns": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "DNS lookup",
        "description": "Perform a DNS lookup for a given domain.",
        "operationId": "dnsLookup",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "DNS records"
          }
        }
      }
    },
    "/api/auth/login": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Login",
        "description": "Authenticate with email and password. Returns user data and sets session cookie.",
        "operationId": "login",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Login successful",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many login attempts"
          }
        }
      }
    },
    "/api/auth/register": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Register new account",
        "description": "Create a new user account and organization.",
        "operationId": "register",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Account created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "409": {
            "description": "Email already exists"
          }
        }
      }
    },
    "/api/auth/logout": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Logout",
        "description": "End current session and clear cookies.",
        "operationId": "logout",
        "responses": {
          "200": {
            "description": "Logged out successfully"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/auth/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get current user",
        "description": "Returns the currently authenticated user's profile, organization, and permissions.",
        "operationId": "getCurrentUser",
        "responses": {
          "200": {
            "description": "User profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/auth/csrf": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Get CSRF token",
        "description": "Get a CSRF token for subsequent write operations. Required for session-based auth.",
        "operationId": "getCsrfToken",
        "responses": {
          "200": {
            "description": "CSRF token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "csrfToken": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/auth/refresh": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Refresh session",
        "description": "Refresh the current session token to extend its lifetime.",
        "operationId": "refreshSession",
        "responses": {
          "200": {
            "description": "Session refreshed"
          },
          "401": {
            "description": "Session expired"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/auth/sessions": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "List active sessions",
        "description": "Get all active sessions for the current user.",
        "operationId": "listSessions",
        "responses": {
          "200": {
            "description": "Active sessions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sessions": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Authentication"
        ],
        "summary": "Revoke session",
        "description": "Revoke a specific session by ID.",
        "operationId": "revokeSession",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Session revoked"
          }
        }
      }
    },
    "/api/auth/2fa": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Enable 2FA",
        "description": "Generate a TOTP secret and QR code to enable two-factor authentication.",
        "operationId": "enable2FA",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "2FA setup data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string"
                    },
                    "qrCode": {
                      "type": "string",
                      "description": "QR code for the authenticator app, as a self-contained image data URL (data:image/svg+xml;base64,...)."
                    },
                    "backupCodes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Authentication"
        ],
        "summary": "Confirm 2FA setup",
        "description": "Confirm 2FA setup by providing a valid TOTP code.",
        "operationId": "confirm2FA",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 6,
                    "maxLength": 6
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "2FA enabled"
          }
        }
      },
      "delete": {
        "tags": [
          "Authentication"
        ],
        "summary": "Disable 2FA",
        "description": "Disable two-factor authentication for the current user.",
        "operationId": "disable2FA",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "2FA disabled"
          }
        }
      }
    },
    "/api/auth/2fa/verify": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify 2FA code",
        "description": "Verify a TOTP code during login when 2FA is enabled.",
        "operationId": "verify2FA",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "code"
                ],
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "tempToken": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "2FA verified, session created"
          },
          "401": {
            "description": "Invalid code"
          }
        }
      }
    },
    "/api/auth/forgot-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Request password reset",
        "description": "Send a password reset email to the specified address.",
        "operationId": "forgotPassword",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reset email sent (always returns 200 to prevent enumeration)"
          }
        }
      },
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Validate reset token",
        "description": "Check if a password reset token is still valid.",
        "operationId": "validateResetToken",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Token is valid"
          },
          "400": {
            "description": "Token expired or invalid"
          }
        }
      }
    },
    "/api/auth/reset-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Reset password",
        "description": "Set a new password using a valid reset token.",
        "operationId": "resetPassword",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token",
                  "password"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 8
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password reset successful"
          },
          "400": {
            "description": "Invalid or expired token"
          }
        }
      }
    },
    "/api/auth/update-password": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Update password",
        "description": "Change the current user's password (requires current password).",
        "operationId": "updatePassword",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "currentPassword",
                  "newPassword"
                ],
                "properties": {
                  "currentPassword": {
                    "type": "string"
                  },
                  "newPassword": {
                    "type": "string",
                    "minLength": 8
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Password updated"
          },
          "401": {
            "description": "Current password incorrect"
          }
        }
      }
    },
    "/api/auth/verify-email": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify email (via link)",
        "description": "Verify email address using the token from the verification email link.",
        "operationId": "verifyEmailGet",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Email verified"
          },
          "400": {
            "description": "Invalid or expired token"
          }
        }
      },
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Verify email (via code)",
        "description": "Verify email address using a verification code.",
        "operationId": "verifyEmailPost",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email verified"
          }
        }
      }
    },
    "/api/auth/resend-verification": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Resend verification email",
        "description": "Resend the email verification link.",
        "operationId": "resendVerification",
        "responses": {
          "200": {
            "description": "Verification email sent"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/auth/oauth/providers": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "List OAuth providers",
        "description": "Get available OAuth providers (Google, GitHub).",
        "operationId": "listOAuthProviders",
        "security": [],
        "responses": {
          "200": {
            "description": "Available providers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "enabled": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/auth/oauth/google": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Initiate Google OAuth",
        "description": "Redirect to Google OAuth consent screen.",
        "operationId": "googleOAuth",
        "security": [],
        "responses": {
          "302": {
            "description": "Redirect to Google"
          }
        }
      }
    },
    "/api/auth/oauth/google/callback": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Google OAuth callback",
        "description": "Handle the Google OAuth callback after user consent.",
        "operationId": "googleOAuthCallback",
        "security": [],
        "responses": {
          "302": {
            "description": "Redirect to dashboard"
          }
        }
      }
    },
    "/api/auth/oauth/github": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Initiate GitHub OAuth",
        "description": "Redirect to GitHub OAuth consent screen.",
        "operationId": "githubOAuth",
        "security": [],
        "responses": {
          "302": {
            "description": "Redirect to GitHub"
          }
        }
      }
    },
    "/api/auth/oauth/github/callback": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "GitHub OAuth callback",
        "description": "Handle the GitHub OAuth callback after user consent.",
        "operationId": "githubOAuthCallback",
        "security": [],
        "responses": {
          "302": {
            "description": "Redirect to dashboard"
          }
        }
      }
    },
    "/api/monitors": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "List monitors",
        "description": "Get all monitors for the current organization with pagination and filtering.",
        "operationId": "listMonitors",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            },
            "description": "Page number. Results are paginated only when `page` is sent; otherwise up to 2,000 monitors are returned in one response."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "operational",
                "degraded",
                "down",
                "pending",
                "changed",
                "paused"
              ]
            },
            "description": "Filter by status. `all` (or no value) returns every monitor; `paused` returns paused monitors."
          },
          {
            "name": "scope",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "site",
                "api"
              ]
            },
            "description": "Product-level one-tap scope. api includes API and GraphQL; site includes every other monitor type."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by monitor type. One value or a comma-separated list, any case, for example `api,graphql`. Values: see StoredMonitorType."
          },
          {
            "name": "enabled",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Search by name or URL"
          },
          {
            "name": "tags",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Comma-separated list of tags"
          },
          {
            "name": "sortBy",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "createdAt",
                "name",
                "status",
                "uptime"
              ],
              "default": "createdAt"
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            }
          },
          {
            "name": "includeSummary",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "On page 1, include exact fleet-wide status/type counts and average uptime without loading every monitor row."
          }
        ],
        "responses": {
          "200": {
            "description": "List of monitors. By default (no `page` query parameter) the response is a bare array of Monitor objects for backward compatibility. When the request sends `Accept: application/json` AND includes a `page` query parameter, the response is the `data`-wrapped paginated envelope shown below.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Monitor"
                      }
                    },
                    {
                      "$ref": "#/components/schemas/MonitorListResponse"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Create monitor",
        "description": "Create a website or endpoint monitor. Uptime checks start right away. Use `locations` for check regions (EU, US, ASIA) and `visualEnabled` / `visualRegion` for screenshots.",
        "operationId": "createMonitor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMonitorRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Monitor created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Monitor"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed. Codes include `INVALID_LOCATION`, `LOCATION_UNSUPPORTED_FOR_TYPE`, `REGION_UNAVAILABLE`, `INVALID_API_CONFIG`, `INVALID_ASSERTION_PATTERN`, `unsafe_url` and `domain_not_found`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Plan or role restriction: `LIMIT_EXCEEDED` (monitor or visual slot limit), `FEATURE_RESTRICTED`, `LOCATION_RESTRICTED`, `VISUAL_VIEWPORT_LIMIT`, or an API key without `monitors:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`DEPENDENCY_EXISTS`: that service is already monitored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Too many monitors created in the last hour.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Monitors"
        ],
        "summary": "Bulk delete monitors",
        "description": "Delete multiple monitors at once.",
        "operationId": "bulkDeleteMonitors",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Monitors deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "deletedCount": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get monitor",
        "description": "Get detailed information about a specific monitor.",
        "operationId": "getMonitor",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitor details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Monitor"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found"
          }
        }
      },
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Update monitor",
        "description": "Update a monitor. Every field is optional; send only what changes. Send `enabled: false` to pause and `enabled: true` to resume. `locations` and `visualRegion` move checks between regions (EU, US, ASIA).",
        "operationId": "updateMonitor",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMonitorRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Monitor updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Monitor"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed. Codes include `INVALID_LOCATION`, `LOCATION_UNSUPPORTED_FOR_TYPE`, `REGION_UNAVAILABLE`, `INVALID_API_CONFIG` and `INVALID_ASSERTION_PATTERN`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Plan or role restriction, for example `LOCATION_RESTRICTED` or `FEATURE_RESTRICTED`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "`ASSERTIONS_CHANGED`: the stored response checks changed since `expectedAssertions` was read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Monitors"
        ],
        "summary": "Delete monitor",
        "description": "Delete a monitor. The monitor and its history can be restored for 24 hours via the restore endpoint; after that it is permanently removed.",
        "operationId": "deleteMonitor",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitor deleted"
          }
        }
      }
    },
    "/api/monitors/{id}/check": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Trigger manual check",
        "description": "Manually trigger a monitor check and get immediate results.",
        "operationId": "triggerCheck",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Check result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResult"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/checks": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get check history",
        "description": "Get recent check results for a monitor with timing breakdown (DNS, connect, TLS, TTFB). Supports time range filtering and optional response body inclusion for API monitors.",
        "operationId": "getMonitorChecks",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 500
            },
            "description": "Number of checks to return"
          },
          {
            "name": "timeRange",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "6h",
                "24h",
                "7d",
                "30d"
              ],
              "default": "24h"
            },
            "description": "Time range to fetch checks for"
          },
          {
            "name": "includeBody",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Include response body (API monitors only, increases payload size)"
          }
        ],
        "responses": {
          "200": {
            "description": "Check history",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "checks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "SUCCESS",
                              "FAILURE",
                              "TIMEOUT",
                              "ERROR"
                            ]
                          },
                          "statusCode": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "responseTime": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Total response time in ms"
                          },
                          "location": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Checker source location for this result."
                          },
                          "error": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "assertionResults": {
                            "description": "API assertion results if configured"
                          },
                          "responseBody": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Only included when includeBody=true"
                          },
                          "firstByteTime": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Time to first byte in ms"
                          },
                          "dnsTime": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "DNS resolution time in ms"
                          },
                          "connectTime": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "TCP connection time in ms"
                          },
                          "tlsTime": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "TLS handshake time in ms"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found"
          },
          "503": {
            "description": "Database unavailable"
          }
        }
      }
    },
    "/api/monitors/{id}/uptime": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get uptime statistics",
        "description": "Get uptime percentage and history for a monitor.",
        "operationId": "getUptime",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "6h",
                "24h",
                "7d",
                "30d",
                "90d",
                "365d"
              ],
              "default": "24h"
            },
            "description": "Preset window. `window` is accepted as an alias."
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Custom range start (ISO date or date-time). Send with `to`."
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Custom range end (ISO date or date-time, a date includes that whole day)."
          }
        ],
        "responses": {
          "200": {
            "description": "Uptime statistics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UptimeResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/response-time": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get response time metrics",
        "description": "Get response time history and statistics.",
        "operationId": "getResponseTime",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "24h",
                "7d",
                "30d"
              ],
              "default": "24h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Response time metrics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResponseTimeResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/dns": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get DNS records",
        "description": "Get DNS record details for a monitor's domain.",
        "operationId": "getMonitorDns",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "DNS records for the monitor's domain"
          }
        }
      }
    },
    "/api/monitors/{id}/pagespeed": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get PageSpeed data",
        "description": "Get cached PageSpeed Insights data for a monitor.",
        "operationId": "getMonitorPagespeed",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PageSpeed results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "metrics": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "The last successful result is retained when later tests fail.",
                      "properties": {
                        "fetchedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When the result was measured."
                        }
                      }
                    },
                    "lastError": {
                      "$ref": "#/components/schemas/PageSpeedFailure"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Trigger PageSpeed check",
        "description": "Trigger a fresh PageSpeed Insights analysis.",
        "operationId": "triggerMonitorPagespeed",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PageSpeed analysis triggered"
          }
        }
      }
    },
    "/api/monitors/{id}/snapshots": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get content snapshots",
        "description": "Get content change detection snapshots for a monitor.",
        "operationId": "getMonitorSnapshots",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Content snapshots"
          }
        }
      }
    },
    "/api/monitors/{id}/channels": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get monitor notification channels",
        "description": "Get notification channels assigned to a specific monitor.",
        "operationId": "getMonitorChannels",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Assigned notification channels"
          }
        }
      },
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Update monitor notification channels",
        "description": "Set which notification channels are assigned to a monitor.",
        "operationId": "updateMonitorChannels",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channelIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Channels updated"
          }
        }
      }
    },
    "/api/monitors/{id}/anomalies": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get anomalies",
        "description": "Get detected anomalies for a monitor.",
        "operationId": "getMonitorAnomalies",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Anomaly data"
          }
        }
      },
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Monitors"
        ],
        "summary": "Create anomaly",
        "description": "Manually create an anomaly record for a monitor.",
        "operationId": "createMonitorAnomaly",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Anomaly created"
          }
        }
      },
      "patch": {
        "tags": [
          "Monitors"
        ],
        "summary": "Update anomaly",
        "description": "Update or acknowledge an anomaly.",
        "operationId": "updateMonitorAnomaly",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Anomaly updated"
          }
        }
      }
    },
    "/api/monitors/{id}/report": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get monitor report",
        "description": "Get a comprehensive report for a monitor.",
        "operationId": "getMonitorReport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitor report data"
          }
        }
      },
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Update monitor report settings",
        "description": "Update report generation settings for a monitor.",
        "operationId": "updateMonitorReport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Report settings updated"
          }
        }
      },
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Monitors"
        ],
        "summary": "Generate monitor report",
        "description": "Trigger generation of a new report for a monitor.",
        "operationId": "generateMonitorReport",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Report generated"
          }
        }
      }
    },
    "/api/monitors/{id}/sub-pages": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "List sub-pages",
        "description": "Get all sub-pages configured for visual monitoring on this monitor.",
        "operationId": "listSubPages",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of sub-pages"
          }
        }
      },
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Add sub-page",
        "description": "Add a new sub-page for visual monitoring.",
        "operationId": "addSubPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "path"
                ],
                "properties": {
                  "path": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sub-page added"
          }
        }
      },
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Update sub-page",
        "description": "Update a sub-page configuration.",
        "operationId": "updateSubPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sub-page updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Monitors"
        ],
        "summary": "Delete sub-page",
        "description": "Remove a sub-page from visual monitoring.",
        "operationId": "deleteSubPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sub-page deleted"
          }
        }
      }
    },
    "/api/monitors/{id}/sub-pages/{subPageId}/capture": {
      "post": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Capture sub-page screenshot",
        "description": "Capture a baseline screenshot for a sub-page.",
        "operationId": "captureSubPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subPageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot captured"
          }
        }
      }
    },
    "/api/monitors/{id}/sub-pages/{subPageId}/visual": {
      "get": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Get sub-page visual data",
        "description": "Get visual monitoring data for a specific sub-page.",
        "operationId": "getSubPageVisual",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "subPageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sub-page visual data"
          }
        }
      }
    },
    "/api/monitors/{id}/visual": {
      "get": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Get visual monitoring data",
        "description": "Get visual monitoring history and screenshots.",
        "operationId": "getVisualData",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Visual monitoring data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VisualDataResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/visual/capture": {
      "post": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Capture screenshot",
        "description": "Capture a new screenshot for visual comparison.",
        "operationId": "captureScreenshot",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Screenshot captured",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "screenshotUrl": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/visual/baseline": {
      "post": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Set visual baseline",
        "description": "Set the current screenshot as the baseline for visual comparisons.",
        "operationId": "setVisualBaseline",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Baseline set"
          }
        }
      }
    },
    "/api/monitors/{id}/visual/compare": {
      "post": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Compare visual snapshots",
        "description": "Compare two visual snapshots and return diff percentage.",
        "operationId": "compareVisual",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Comparison result with diff percentage"
          }
        }
      }
    },
    "/api/monitors/{id}/visual/delete": {
      "post": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Delete visual snapshots (POST)",
        "description": "Delete specific visual snapshots by IDs.",
        "operationId": "deleteVisualSnapshotsPost",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshots deleted"
          }
        }
      },
      "delete": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Delete visual snapshots",
        "description": "Delete visual monitoring data.",
        "operationId": "deleteVisualSnapshots",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Snapshots deleted"
          }
        }
      },
      "get": {
        "tags": [
          "Visual Monitoring"
        ],
        "summary": "Get deletable snapshots",
        "description": "List visual snapshots that can be deleted.",
        "operationId": "getDeletableSnapshots",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of deletable snapshots"
          }
        }
      }
    },
    "/api/monitors/alert-settings": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get monitor alert settings",
        "description": "Get alert settings for all monitors in the organization.",
        "operationId": "getMonitorAlertSettings",
        "responses": {
          "200": {
            "description": "Monitor alert settings"
          }
        }
      }
    },
    "/api/monitors/bulk-alerts": {
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Bulk update monitor alerts",
        "description": "Changes alert settings and notification channels on up to 2,000 monitors in one all-or-nothing change. Every monitor and channel must belong to your organization, or nothing changes. Any role except Viewer; API keys need the `monitors:write` scope. Limited to 30 requests per minute per organization.",
        "operationId": "bulkUpdateAlerts",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateAlertsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updatedCount": {
                      "type": "integer",
                      "description": "Monitors whose alert fields were updated, or the number of IDs sent when `updates` changed no fields."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Fails validation (`details` holds `formErrors` and `fieldErrors`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, the API key lacks the `monitors:write` scope or plan API access, a monitor ID is not in your organization or repeats, or a channel ID is not in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 requests in a minute to this bulk route for the organization",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "ISO time the window resets.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkRateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/content": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Content change detection",
        "description": "Check content changes for a URL.",
        "operationId": "checkContent",
        "responses": {
          "200": {
            "description": "Content check result"
          }
        }
      }
    },
    "/api/monitors/export": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Export monitors",
        "description": "Export all monitors data as CSV or JSON.",
        "operationId": "exportMonitors",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "csv",
                "json"
              ],
              "default": "csv"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Exported monitor data"
          }
        }
      }
    },
    "/api/monitors/test": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Test monitor URL",
        "description": "Test a URL before creating a monitor to verify it's reachable.",
        "operationId": "testMonitor",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Test result"
          }
        }
      }
    },
    "/api/monitors/populate-favicons": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Populate favicons",
        "description": "Fetch and store favicons for all monitors that don't have one.",
        "operationId": "populateFavicons",
        "responses": {
          "200": {
            "description": "Favicons populated"
          }
        }
      }
    },
    "/api/monitor-check": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Worker monitor check",
        "description": "Internal endpoint used by the worker to report check results.",
        "operationId": "workerMonitorCheck",
        "responses": {
          "200": {
            "description": "Check recorded"
          }
        }
      },
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get monitor check queue status",
        "description": "Get the status of the monitor check queue.",
        "operationId": "getMonitorCheckQueue",
        "responses": {
          "200": {
            "description": "Queue status"
          }
        }
      }
    },
    "/api/servers": {
      "get": {
        "tags": [
          "Servers"
        ],
        "summary": "List servers",
        "description": "Get all servers for the organization.",
        "operationId": "listServers",
        "security": [
          {
            "SessionAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of servers",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "403": {
            "description": "Server monitoring not available on current plan or missing servers:read scope"
          }
        }
      },
      "post": {
        "tags": [
          "Servers"
        ],
        "summary": "Create server",
        "description": "Register a new server for monitoring. Returns the server token for agent installation.",
        "operationId": "createServer",
        "security": [
          {
            "SessionAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "hostname": {
                    "type": "string"
                  },
                  "ipAddress": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Server created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "server": {
                      "$ref": "#/components/schemas/Server"
                    },
                    "token": {
                      "type": "string",
                      "description": "Agent authentication token (shown only once)"
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Server limit reached"
          }
        }
      }
    },
    "/api/servers/{id}": {
      "get": {
        "tags": [
          "Servers"
        ],
        "summary": "Get server details",
        "description": "Get detailed information about a specific server including recent metrics and top processes.",
        "operationId": "getServer",
        "security": [
          {
            "SessionAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "server": {
                      "$ref": "#/components/schemas/Server"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Server not found"
          }
        }
      },
      "patch": {
        "tags": [
          "Servers"
        ],
        "summary": "Update server",
        "description": "Update server name, tags, or alert configuration.",
        "operationId": "updateServer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "alertConfig": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Server updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Servers"
        ],
        "summary": "Delete server",
        "description": "Remove a server and all its monitoring data.",
        "operationId": "deleteServer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server deleted"
          }
        }
      }
    },
    "/api/servers/{id}/metrics": {
      "get": {
        "tags": [
          "Servers"
        ],
        "summary": "Get server metrics",
        "description": "Get historical server metrics (CPU, memory, disk, network) with configurable time periods.",
        "operationId": "getServerMetrics",
        "security": [
          {
            "SessionAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1h",
                "6h",
                "24h",
                "7d",
                "30d"
              ],
              "default": "1h"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server metrics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerMetricsResponse"
                }
              }
            }
          },
          "404": {
            "description": "Server not found"
          }
        }
      }
    },
    "/api/servers/{id}/alerts": {
      "get": {
        "tags": [
          "Server Alerts"
        ],
        "summary": "Get server alert history",
        "description": "Get historical alerts for a specific server (CPU, memory, disk threshold breaches, offline events).",
        "operationId": "getServerAlerts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "maximum": 200
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server alert history",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerAlertListResponse"
                }
              }
            }
          },
          "404": {
            "description": "Server not found"
          }
        }
      }
    },
    "/api/servers/agent/install.sh": {
      "get": {
        "tags": [
          "Servers"
        ],
        "summary": "Get agent install script",
        "description": "Download the server monitoring agent installation shell script.",
        "operationId": "getAgentInstallScript",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Shell script",
            "content": {
              "text/x-shellscript": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/servers/agent/report": {
      "post": {
        "tags": [
          "Servers"
        ],
        "summary": "Agent metrics report",
        "description": "Endpoint for the server agent to submit metrics data. Authenticated via server token.",
        "operationId": "agentReport",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string"
                  },
                  "cpu": {
                    "type": "object"
                  },
                  "memory": {
                    "type": "object"
                  },
                  "disk": {
                    "type": "object"
                  },
                  "network": {
                    "type": "object"
                  },
                  "processes": {
                    "type": "array",
                    "maxItems": 50,
                    "description": "Top processes, at most 50.",
                    "items": {
                      "type": "object",
                      "additionalProperties": true,
                      "properties": {
                        "pid": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "name": {
                          "type": "string"
                        },
                        "command": {
                          "type": "string"
                        },
                        "cpuPercent": {
                          "type": "number"
                        },
                        "memoryPercent": {
                          "type": "number"
                        },
                        "memoryBytes": {
                          "type": "number"
                        },
                        "status": {
                          "type": "string"
                        },
                        "user": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Metrics recorded"
          },
          "401": {
            "description": "Invalid server token"
          }
        }
      }
    },
    "/api/notification-channels": {
      "get": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "List notification channels",
        "description": "Get all notification channels for the organization.",
        "operationId": "listNotificationChannels",
        "responses": {
          "200": {
            "description": "List of notification channels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "channels": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/NotificationChannel"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Create notification channel",
        "description": "Create a notification channel. Channel types available depend on the plan (403 `PLAN_LIMIT_EXCEEDED`).",
        "operationId": "createNotificationChannel",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNotificationChannelRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Channel created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "channel": {
                      "$ref": "#/components/schemas/NotificationChannel"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed or required settings missing for the channel type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Channel type not on your plan (`PLAN_LIMIT_EXCEEDED`), read-only role, or an API key without `channels:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/notification-channels/{id}": {
      "get": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Get notification channel",
        "description": "Get details of a specific notification channel.",
        "operationId": "getNotificationChannel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channel details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationChannel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Update notification channel",
        "description": "Update an existing notification channel.",
        "operationId": "updateNotificationChannel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNotificationChannelRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Channel updated"
          }
        }
      },
      "patch": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Toggle notification channel",
        "description": "Enable or disable a notification channel.",
        "operationId": "toggleNotificationChannel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Channel toggled"
          }
        }
      },
      "delete": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Delete notification channel",
        "description": "Delete a notification channel.",
        "operationId": "deleteNotificationChannel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Channel deleted"
          }
        }
      }
    },
    "/api/notification-channels/{id}/test": {
      "post": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Test notification channel",
        "description": "Send a test notification to verify the channel is configured correctly.",
        "operationId": "testNotificationChannel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Test notification sent. The test goes to every destination real alerts reach. When real alerts would not reach this channel, wouldReceiveAlerts is false and reason says why.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "sentAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "wouldReceiveAlerts": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "disabled",
                        "paused",
                        "plan",
                        "unverified",
                        null
                      ]
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "target": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "sent",
                              "failed",
                              "skipped"
                            ]
                          },
                          "error": {
                            "type": "string"
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "unverified"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/push-subscriptions": {
      "get": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "List push subscriptions",
        "description": "List all browser push notification subscriptions for the current organization.",
        "operationId": "listPushSubscriptions",
        "responses": {
          "200": {
            "description": "Push subscriptions list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "subscriptions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "channelId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "channelName": {
                            "type": "string"
                          },
                          "endpoint": {
                            "type": "string",
                            "format": "uri"
                          },
                          "name": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "userId": {
                            "type": "string",
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Register push subscription",
        "description": "Register a browser push notification subscription. Creates a new PUSH notification channel and auto-assigns it to all existing monitors. Requires write access and a plan that supports push notifications.",
        "operationId": "createPushSubscription",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subscription"
                ],
                "properties": {
                  "subscription": {
                    "type": "object",
                    "required": [
                      "endpoint",
                      "keys"
                    ],
                    "properties": {
                      "endpoint": {
                        "type": "string",
                        "format": "uri"
                      },
                      "keys": {
                        "type": "object",
                        "required": [
                          "p256dh",
                          "auth"
                        ],
                        "properties": {
                          "p256dh": {
                            "type": "string"
                          },
                          "auth": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Optional friendly name for this browser"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Push subscription registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "channelId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "403": {
            "description": "Push notifications not available on current plan"
          }
        }
      },
      "delete": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Remove push subscription",
        "description": "Remove a browser push subscription by endpoint URL. If it is the last subscription in its channel, the entire channel is deleted.",
        "operationId": "deletePushSubscription",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "endpoint"
                ],
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "format": "uri",
                    "description": "The push subscription endpoint URL to remove"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Push subscription removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error"
          },
          "404": {
            "description": "Subscription not found"
          }
        }
      }
    },
    "/api/notification-preferences": {
      "get": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Get notification preferences",
        "description": "Get the user's notification preferences (which event types trigger which channels).",
        "operationId": "getNotificationPreferences",
        "responses": {
          "200": {
            "description": "Notification preferences"
          }
        }
      },
      "put": {
        "tags": [
          "Notification Channels"
        ],
        "summary": "Update notification preferences",
        "description": "Update notification preferences for event types.",
        "operationId": "updateNotificationPreferences",
        "responses": {
          "200": {
            "description": "Preferences updated"
          }
        }
      }
    },
    "/api/alerts": {
      "get": {
        "tags": [
          "Alerts"
        ],
        "summary": "List alerts",
        "description": "Get all alerts with filtering and pagination.",
        "operationId": "listAlerts",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "ACKNOWLEDGED",
                "RESOLVED"
              ]
            }
          },
          {
            "name": "severity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "INFO",
                "WARNING",
                "CRITICAL"
              ]
            }
          },
          {
            "name": "monitorId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of alerts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/alerts/{id}/acknowledge": {
      "post": {
        "tags": [
          "Alerts"
        ],
        "summary": "Acknowledge alert",
        "description": "Mark an alert as acknowledged.",
        "operationId": "acknowledgeAlert",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Alert acknowledged",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Alert"
                }
              }
            }
          }
        }
      }
    },
    "/api/alerts/{id}/resolve": {
      "post": {
        "tags": [
          "Alerts"
        ],
        "summary": "Resolve alert",
        "description": "Mark an alert as resolved.",
        "operationId": "resolveAlert",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Alert resolved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Alert"
                }
              }
            }
          }
        }
      }
    },
    "/api/alerts/pause-all": {
      "post": {
        "tags": [
          "Alerts"
        ],
        "summary": "Pause all alerts",
        "description": "Pause or resume all alerting for the organization. While paused, no notification channel receives alerts; alerts still appear in the dashboard. Each channel keeps its own on or off setting, so resuming does not turn on a channel that was switched off.",
        "operationId": "pauseAllAlerts",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "paused"
                ],
                "properties": {
                  "paused": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Alerts paused or resumed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "paused": {
                      "type": "boolean"
                    },
                    "pausedAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "channelsUpdated": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Alerts"
        ],
        "summary": "Get alerts paused status",
        "description": "Check whether all alerts are currently paused.",
        "operationId": "getAlertsPausedStatus",
        "responses": {
          "200": {
            "description": "Paused status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "paused": {
                      "type": "boolean"
                    },
                    "pausedAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "partiallyPaused": {
                      "type": "boolean",
                      "description": "Alerts are not paused, but some channels are switched off."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/alert-rules": {
      "get": {
        "tags": [
          "Alert Rules"
        ],
        "summary": "List alert rules",
        "description": "Get all alert rules for the organization. Each rule carries supported and unsupportedReason; unsupported rules are never evaluated.",
        "operationId": "listAlertRules",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of alert rules",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRuleListResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Alert Rules"
        ],
        "summary": "Create alert rule",
        "description": "Create a rule that alerts when one monitor's response time or uptime crosses a threshold. monitorId is required. Down alerts, repeated failures and SSL expiry are built-in alerts, so rules do not accept those conditions.",
        "operationId": "createAlertRule",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAlertRuleRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Alert rule created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRuleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or the request uses a condition alert rules do not support (status_change, consecutive_failures, ssl_expiry). Those are covered by the built-in alerts.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AlertRuleConditionNotSupportedResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorResponse"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found in this organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/alert-rules/{id}": {
      "get": {
        "tags": [
          "Alert Rules"
        ],
        "summary": "Get alert rule",
        "description": "Get details of a specific alert rule.",
        "operationId": "getAlertRule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alert rule details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRuleResponse"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Alert Rules"
        ],
        "summary": "Update alert rule",
        "description": "Update an existing alert rule.",
        "operationId": "updateAlertRule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAlertRuleRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Alert rule updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertRuleResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation failed, or the request uses a condition alert rules do not support (status_change, consecutive_failures, ssl_expiry). Those are covered by the built-in alerts.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/AlertRuleConditionNotSupportedResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ErrorResponse"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Alert rule or monitor not found"
          }
        }
      },
      "delete": {
        "tags": [
          "Alert Rules"
        ],
        "summary": "Delete alert rule",
        "description": "Delete an alert rule.",
        "operationId": "deleteAlertRule",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alert rule deleted"
          }
        }
      }
    },
    "/api/alert-groups": {
      "get": {
        "tags": [
          "Alert Groups"
        ],
        "summary": "List alert groups",
        "description": "Get all alert groups for the organization.",
        "operationId": "listAlertGroups",
        "responses": {
          "200": {
            "description": "List of alert groups"
          }
        }
      }
    },
    "/api/alert-groups/{id}": {
      "get": {
        "tags": [
          "Alert Groups"
        ],
        "summary": "Get alert group",
        "description": "Get details of a specific alert group.",
        "operationId": "getAlertGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alert group details"
          }
        }
      }
    },
    "/api/alert-groups/{id}/alerts": {
      "get": {
        "tags": [
          "Alert Groups"
        ],
        "summary": "Get alerts in group",
        "description": "Get all alerts belonging to a specific alert group.",
        "operationId": "getAlertGroupAlerts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alerts in the group"
          }
        }
      }
    },
    "/api/alert-groups/{id}/acknowledge": {
      "post": {
        "tags": [
          "Alert Groups"
        ],
        "summary": "Acknowledge alert group",
        "description": "Acknowledge all alerts in a group.",
        "operationId": "acknowledgeAlertGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alert group acknowledged"
          }
        }
      }
    },
    "/api/alert-groups/{id}/resolve": {
      "post": {
        "tags": [
          "Alert Groups"
        ],
        "summary": "Resolve alert group",
        "description": "Resolve all alerts in a group.",
        "operationId": "resolveAlertGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Alert group resolved"
          }
        }
      }
    },
    "/api/alert-groups/{id}/summarize": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Alert Groups"
        ],
        "summary": "Summarize alert group",
        "description": "Generate an AI summary of the alert group.",
        "operationId": "summarizeAlertGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AI-generated summary"
          }
        }
      }
    },
    "/api/incidents": {
      "get": {
        "tags": [
          "Incidents"
        ],
        "summary": "List incidents",
        "description": "List incidents, open ones first, newest first within each group.",
        "operationId": "listIncidents",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "resolved",
                "all",
                "INVESTIGATING",
                "IDENTIFIED",
                "MONITORING",
                "RESOLVED",
                "POSTMORTEM"
              ],
              "default": "all"
            },
            "description": "`active` returns open incidents (investigating, identified, monitoring); `resolved` returns resolved and postmortem ones; an exact status matches one status. Case-insensitive."
          },
          {
            "name": "severity",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "CRITICAL",
                "HIGH",
                "MEDIUM",
                "LOW",
                "INFO"
              ]
            }
          },
          {
            "name": "monitorId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search title, description and cause."
          },
          {
            "name": "startDate",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO date or date-time."
          },
          {
            "name": "endDate",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO date or date-time."
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            },
            "description": "Values above 100 are served 100 rows."
          }
        ],
        "responses": {
          "200": {
            "description": "Incidents",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "incidents": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Incident"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid query parameters, for example an unknown status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Incidents"
        ],
        "summary": "Create incident",
        "description": "Manually create a new incident.",
        "operationId": "createIncident",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorId",
                  "title"
                ],
                "properties": {
                  "monitorId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "severity": {
                    "type": "string",
                    "enum": [
                      "CRITICAL",
                      "HIGH",
                      "MEDIUM",
                      "LOW"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Incident created"
          }
        }
      }
    },
    "/api/incidents/{id}": {
      "get": {
        "tags": [
          "Incidents"
        ],
        "summary": "Get incident",
        "description": "Get details of a specific incident.",
        "operationId": "getIncident",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Incident details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Incident"
                }
              }
            }
          },
          "404": {
            "description": "Incident not found"
          }
        }
      },
      "put": {
        "tags": [
          "Incidents"
        ],
        "summary": "Update incident",
        "description": "Change an incident: status, severity, title, description, resolution notes, acknowledgement or auto-resolve. Every field is optional. `{ \"acknowledged\": true }` acknowledges; `{ \"status\": \"RESOLVED\" }` resolves. A status change is sent at once to the incident's alert channels and status page subscribers, unless `notify` is false.",
        "operationId": "updateIncident",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIncidentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Incident updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "incident": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "severity": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "acknowledgedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "acknowledgedById": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    },
                    "warning": {
                      "type": "string"
                    },
                    "replayed": {
                      "type": "boolean",
                      "description": "true when this repeated a status change already made with the same actionId. Nothing was changed or sent again."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Read-only role, or an API key without `incidents:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Incident not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The actionId was already used on another incident.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Incidents"
        ],
        "summary": "Delete incident",
        "description": "Delete an incident.",
        "operationId": "deleteIncident",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Incident deleted"
          }
        }
      },
      "patch": {
        "tags": [
          "Incidents"
        ],
        "summary": "Update incident (partial)",
        "description": "Same as PUT: every field is optional. The dashboard acknowledges with `PATCH { \"acknowledged\": true }`.",
        "operationId": "patchIncident",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateIncidentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Incident updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    },
                    "incident": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "severity": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "acknowledgedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "acknowledgedById": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    },
                    "warning": {
                      "type": "string"
                    },
                    "replayed": {
                      "type": "boolean",
                      "description": "true when this repeated a status change already made with the same actionId. Nothing was changed or sent again."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Read-only role, or an API key without `incidents:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Incident not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The actionId was already used on another incident.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/incidents/{id}/summarize": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Incidents"
        ],
        "summary": "Generate incident summary",
        "description": "Generate an AI-powered summary and postmortem for an incident.",
        "operationId": "summarizeIncident",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "AI-generated summary"
          }
        }
      },
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Incidents"
        ],
        "summary": "Get incident summary",
        "description": "Get the cached AI summary for an incident.",
        "operationId": "getIncidentSummary",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cached summary"
          }
        }
      }
    },
    "/api/status-pages": {
      "get": {
        "tags": [
          "Status Pages"
        ],
        "summary": "List status pages",
        "description": "Get all status pages for the organization.",
        "operationId": "listStatusPages",
        "responses": {
          "200": {
            "description": "List of status pages"
          }
        }
      },
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Create status page",
        "description": "Create a status page. Pages are public unless `public` is false.",
        "operationId": "createStatusPage",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "slug"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "public": {
                    "type": "boolean",
                    "default": true,
                    "description": "Whether the page is publicly visible."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Status page created. Body: `{ statusPage, message }`."
          },
          "400": {
            "description": "Name or slug missing, or the request body is not valid JSON (`Invalid JSON body`) or is not a JSON object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "Trial expired or workspace suspended"
          },
          "403": {
            "description": "No workspace membership, or status page limit reached (`code: LIMIT_EXCEEDED` with `limit` and `current`)"
          },
          "503": {
            "description": "Workspace status could not be checked; try again"
          }
        }
      }
    },
    "/api/status-pages/{id}": {
      "get": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Get status page",
        "description": "Get details of a specific status page.",
        "operationId": "getStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status page details"
          }
        }
      },
      "patch": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Update status page",
        "description": "Update a status page's configuration.",
        "operationId": "updateStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status page updated"
          },
          "400": {
            "description": "Invalid uptime or incident history window, invalid sort mode, invalid theme, or the request body is not valid JSON (`Invalid JSON body`) or is not a JSON object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Delete status page",
        "description": "Delete a status page.",
        "operationId": "deleteStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status page deleted"
          }
        }
      }
    },
    "/api/status-pages/{id}/monitors": {
      "get": {
        "tags": [
          "Status Pages"
        ],
        "summary": "List monitors on status page",
        "description": "List the monitors linked to a status page in display order, with each monitor's current status and its group assignment on this page.",
        "operationId": "listStatusPageMonitors",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitors on the status page, ordered by `order` ascending",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "monitors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StatusPageMonitorListItem"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Add monitors to status page",
        "description": "Add one monitor (`monitorId`) or several (`monitorIds`, which takes precedence when non-empty) to the end of the status page's monitor order. New links start ungrouped with default display options; use the update endpoint to set a display name, group or order. Monitors outside the caller's organization are ignored and monitors already on the page are skipped. Requires the Owner, Admin or Developer role.",
        "operationId": "addMonitorToStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Provide `monitorId` or a non-empty `monitorIds` array. Other fields are ignored.",
                "properties": {
                  "monitorId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "A single monitor to add"
                  },
                  "monitorIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Monitors to add in one request. Used instead of `monitorId` when non-empty."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Monitors added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "3 monitor(s) added to status page"
                    },
                    "added": {
                      "type": "integer",
                      "description": "Number of requested monitors found in the organization, including any that were already on the page and therefore skipped"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Neither `monitorId` nor `monitorIds` provided (`Monitor ID is required`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found, or none of the requested monitors belong to the caller's organization (`No valid monitors found`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/monitors/{monitorId}": {
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Remove monitor from status page",
        "description": "Remove a monitor from a status page.",
        "operationId": "removeMonitorFromStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "monitorId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitor removed"
          }
        }
      },
      "patch": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Update status page monitor display",
        "description": "Change how a linked monitor appears on the status page: display name, which details are shown, position and group. Fields with the wrong type are ignored. Requires the Owner, Admin or Developer role.",
        "operationId": "updateStatusPageMonitor",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "monitorId",
            "in": "path",
            "required": true,
            "description": "Monitor ID (not the link ID)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "displayName": {
                    "type": "string",
                    "description": "Name shown on the status page. An empty string clears it so the monitor name is used."
                  },
                  "showGraph": {
                    "type": "boolean",
                    "description": "Show the uptime graph"
                  },
                  "showResponseTime": {
                    "type": "boolean",
                    "description": "Show response time"
                  },
                  "showSSL": {
                    "type": "boolean",
                    "description": "Show SSL certificate status"
                  },
                  "order": {
                    "type": "integer",
                    "description": "Display position"
                  },
                  "groupId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Group on this status page to place the monitor in, or null to ungroup it. A group with a tag rule releases monitors that do not carry its tag on its next sync."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Display options updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusPageMonitor": {
                      "$ref": "#/components/schemas/StatusPageMonitorLink"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unknown group for this status page, or the request body is not valid JSON (`Invalid JSON body`) or is not a JSON object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found, the monitor is not on this status page (`Monitor is not linked to this status page`), or `groupId` is not a group on this page (`Status page group not found`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/custom-domain": {
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Set custom domain",
        "description": "Configure a custom domain for a status page. The response includes the CNAME and TXT ownership records to publish. Requires an owner or admin role.",
        "operationId": "setCustomDomain",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Custom domain configured"
          },
          "400": {
            "description": "Domain missing or invalid, or the request body is not valid JSON (`Invalid JSON body`) or is not a JSON object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Verify custom domain",
        "description": "Verify DNS configuration for a custom domain. A domain that is not verified yet needs a CNAME record pointing to status.visualsentinel.com and a TXT record named _visualsentinel.<domain> with the value visualsentinel-verify=<verifyToken>. Already verified domains are not re-checked. Requires an owner or admin role.",
        "operationId": "verifyCustomDomain",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Domain verification result"
          }
        }
      },
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Remove custom domain",
        "description": "Remove the custom domain from a status page.",
        "operationId": "removeCustomDomain",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Custom domain removed"
          }
        }
      }
    },
    "/api/teams": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "List teams",
        "description": "Retired. Always returns 410 Gone; use `/api/organization` instead.",
        "operationId": "listTeams",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Create team",
        "description": "Retired. Always returns 410 Gone; use `/api/organization` instead.",
        "operationId": "createTeam",
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/teams/{id}": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "Get team",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "getTeam",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "put": {
        "tags": [
          "Teams"
        ],
        "summary": "Update team",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "updateTeam",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Delete team",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "deleteTeam",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/teams/{id}/members": {
      "get": {
        "tags": [
          "Teams"
        ],
        "summary": "List team members",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "listTeamMembers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "post": {
        "tags": [
          "Teams"
        ],
        "summary": "Add team member",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "addTeamMember",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "delete": {
        "tags": [
          "Teams"
        ],
        "summary": "Remove team member",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/members/{id}` instead.",
        "operationId": "removeTeamMember",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/members/{id}.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/organization": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get organization",
        "description": "Get the current organization's profile.",
        "operationId": "getOrganization",
        "responses": {
          "200": {
            "description": "Organization profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Organization"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "Organization"
        ],
        "summary": "Update organization",
        "description": "Update the organization's profile (name, slug, logo, website, timezone).",
        "operationId": "updateOrganization",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "slug": {
                    "type": "string",
                    "maxLength": 50
                  },
                  "logo": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string",
                    "format": "uri"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "billingEmail": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Organization updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Delete organization",
        "description": "Permanently delete the organization and all its data. Requires OWNER role.",
        "operationId": "deleteOrganization",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Organization deleted"
          }
        }
      }
    },
    "/api/organization/settings": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get organization settings",
        "description": "Get organization-level settings (alert defaults, preferences).",
        "operationId": "getOrganizationSettings",
        "responses": {
          "200": {
            "description": "Organization settings"
          }
        }
      },
      "patch": {
        "tags": [
          "Organization"
        ],
        "summary": "Update organization settings",
        "description": "Update organization-level settings.",
        "operationId": "updateOrganizationSettings",
        "responses": {
          "200": {
            "description": "Settings updated"
          }
        }
      }
    },
    "/api/organization/members/{id}": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get organization member",
        "description": "Get details of a specific organization member.",
        "operationId": "getOrganizationMember",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Member details"
          }
        }
      },
      "put": {
        "tags": [
          "Organization"
        ],
        "summary": "Update member role",
        "description": "Update an organization member's role.",
        "operationId": "updateMemberRole",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "role"
                ],
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "ADMIN",
                      "MEMBER",
                      "VIEWER"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Member role updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Remove organization member",
        "description": "Remove a member from the organization.",
        "operationId": "removeOrganizationMember",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Member removed"
          }
        }
      }
    },
    "/api/organization/invitations": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "List invitations",
        "description": "Get all pending invitations for the organization.",
        "operationId": "listInvitations",
        "responses": {
          "200": {
            "description": "Pending invitations"
          }
        }
      },
      "post": {
        "tags": [
          "Organization"
        ],
        "summary": "Send invitation",
        "description": "Send an invitation to join the organization.",
        "operationId": "sendInvitation",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "role"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "ADMIN",
                      "MEMBER",
                      "VIEWER"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Invitation sent"
          }
        }
      }
    },
    "/api/organization/invitations/{id}": {
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Cancel invitation",
        "description": "Cancel a pending invitation.",
        "operationId": "cancelInvitation",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invitation cancelled"
          }
        }
      }
    },
    "/api/organization/invitations/accept": {
      "post": {
        "tags": [
          "Organization"
        ],
        "summary": "Accept invitation",
        "description": "Accept an organization invitation using the invitation token.",
        "operationId": "acceptInvitation",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Invitation accepted"
          }
        }
      }
    },
    "/api/organization/invitations/verify": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Verify invitation token",
        "description": "Verify an invitation token is valid and return invitation details.",
        "operationId": "verifyInvitation",
        "security": [],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Invitation details"
          },
          "400": {
            "description": "Invalid or expired token"
          }
        }
      }
    },
    "/api/organization/branding": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get branding settings",
        "description": "Get white-label branding configuration.",
        "operationId": "getBranding",
        "responses": {
          "200": {
            "description": "Branding settings"
          }
        }
      },
      "put": {
        "tags": [
          "Organization"
        ],
        "summary": "Update branding",
        "description": "Update white-label branding configuration (colors, logo, custom domain).",
        "operationId": "updateBranding",
        "responses": {
          "200": {
            "description": "Branding updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Reset branding",
        "description": "Reset branding to default Visual Sentinel branding.",
        "operationId": "resetBranding",
        "responses": {
          "200": {
            "description": "Branding reset"
          }
        }
      }
    },
    "/api/organization/logo": {
      "post": {
        "tags": [
          "Organization"
        ],
        "summary": "Upload logo",
        "description": "Upload an organization logo image.",
        "operationId": "uploadLogo",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo uploaded"
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Delete logo",
        "description": "Remove the organization logo.",
        "operationId": "deleteLogo",
        "responses": {
          "200": {
            "description": "Logo deleted"
          }
        }
      }
    },
    "/api/organization/email-templates": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get email templates",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/branding` instead.",
        "operationId": "getEmailTemplates",
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/branding.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "put": {
        "tags": [
          "Organization"
        ],
        "summary": "Update email templates",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/branding` instead.",
        "operationId": "updateEmailTemplates",
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/branding.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Reset email templates",
        "description": "Retired. Always returns 410 Gone; use `/api/organization/branding` instead.",
        "operationId": "resetEmailTemplates",
        "responses": {
          "410": {
            "description": "Retired. Use /api/organization/branding.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/organization/smtp": {
      "get": {
        "tags": [
          "Organization"
        ],
        "summary": "Get SMTP settings",
        "description": "Get custom SMTP configuration for sending emails.",
        "operationId": "getSmtpSettings",
        "responses": {
          "200": {
            "description": "SMTP settings"
          }
        }
      },
      "post": {
        "tags": [
          "Organization"
        ],
        "summary": "Test SMTP settings",
        "description": "Send a test email using the provided SMTP configuration.",
        "operationId": "testSmtpSettings",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Test email sent"
          }
        }
      },
      "put": {
        "tags": [
          "Organization"
        ],
        "summary": "Update SMTP settings",
        "description": "Update custom SMTP configuration.",
        "operationId": "updateSmtpSettings",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "SMTP settings updated"
          }
        }
      },
      "delete": {
        "tags": [
          "Organization"
        ],
        "summary": "Delete SMTP settings",
        "description": "Remove custom SMTP configuration and revert to default.",
        "operationId": "deleteSmtpSettings",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "SMTP settings removed"
          }
        }
      }
    },
    "/api/organization/leave": {
      "post": {
        "tags": [
          "Organization"
        ],
        "summary": "Leave organization",
        "description": "Leave the current organization. Owners cannot leave; they must transfer ownership to another member first. After leaving, the user is switched to their next available organization. Session only: an API key gets 403 with code `SESSION_REQUIRED`.",
        "operationId": "leaveOrganization",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successfully left the organization",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "switchTo": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid",
                      "description": "Organization ID to switch to, or null if no other memberships"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Owners cannot leave. Transfer ownership first."
          },
          "404": {
            "description": "Not a member of this organization"
          },
          "503": {
            "description": "Database unavailable"
          }
        }
      }
    },
    "/api/maintenance": {
      "get": {
        "tags": [
          "Maintenance"
        ],
        "summary": "List maintenance windows",
        "description": "List maintenance windows that occur between `from` and `to` (default: 90 days ago to about a year ahead).",
        "operationId": "listMaintenanceWindows",
        "responses": {
          "200": {
            "description": "Maintenance windows",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "maintenanceWindows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MaintenanceWindow"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid `from` or `to`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "scheduled",
                "in-progress",
                "completed",
                "cancelled"
              ]
            }
          }
        ]
      },
      "post": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Create maintenance window",
        "description": "Schedule a maintenance window. Alerts for the linked monitors are suppressed while it is active, and status pages show it.",
        "operationId": "createMaintenanceWindow",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMaintenanceWindowRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Maintenance window created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "maintenanceWindow": {
                      "$ref": "#/components/schemas/MaintenanceWindow"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`title`, `startTime` or `endTime` missing or invalid, end not after start, longer than 90 days, or an unknown `recurrenceKind`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Read-only role or an API key without `maintenance:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/maintenance/{id}": {
      "get": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Get maintenance window",
        "description": "Get details of a specific maintenance window.",
        "operationId": "getMaintenanceWindow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Maintenance window details"
          }
        }
      },
      "patch": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Update maintenance window",
        "description": "Update a maintenance window. Send only the fields that change.",
        "operationId": "updateMaintenanceWindow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Maintenance window updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "maintenanceWindow": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "title": {
                          "type": "string"
                        }
                      }
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid dates, end not after start, longer than 90 days, or an unknown `recurrenceKind`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Maintenance window not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMaintenanceWindowRequest"
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Delete maintenance window",
        "description": "Delete a maintenance window.",
        "operationId": "deleteMaintenanceWindow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Maintenance window deleted"
          }
        }
      }
    },
    "/api/billing/checkout": {
      "post": {
        "tags": [
          "Billing"
        ],
        "summary": "Create checkout session",
        "description": "Create a Paddle checkout session for subscription purchase.",
        "operationId": "createCheckout",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "free",
                      "starter",
                      "business",
                      "agency"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "billing": {
                    "type": "string",
                    "enum": [
                      "monthly",
                      "yearly"
                    ],
                    "default": "monthly"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout session URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "checkoutUrl": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/billing/portal": {
      "post": {
        "tags": [
          "Billing"
        ],
        "summary": "Get billing portal URL",
        "description": "Get a Paddle customer portal URL for managing subscriptions.",
        "operationId": "getBillingPortal",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Portal URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/billing/ai-usage": {
      "get": {
        "tags": [
          "Billing"
        ],
        "summary": "Get AI usage",
        "description": "Get AI feature usage for the current billing period.",
        "operationId": "getAiUsage",
        "responses": {
          "200": {
            "description": "AI usage data"
          }
        }
      }
    },
    "/api/integrations/google/authorize": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "Initiate Google integration OAuth",
        "description": "Redirect to Google OAuth for Search Console / Analytics integration.",
        "operationId": "googleIntegrationOAuth",
        "responses": {
          "302": {
            "description": "Redirect to Google"
          }
        }
      }
    },
    "/api/integrations/google/callback": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "Google integration OAuth callback",
        "description": "Handle Google OAuth callback for integration setup.",
        "operationId": "googleIntegrationCallback",
        "responses": {
          "302": {
            "description": "Redirect to settings"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/integrations/google/properties": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "List Google properties",
        "description": "List available Google Search Console properties.",
        "operationId": "listGoogleProperties",
        "responses": {
          "200": {
            "description": "Google properties"
          }
        }
      },
      "post": {
        "tags": [
          "Integrations"
        ],
        "summary": "Select Google property",
        "description": "Select a Google Search Console property to connect.",
        "operationId": "selectGoogleProperty",
        "responses": {
          "200": {
            "description": "Property selected"
          }
        }
      }
    },
    "/api/integrations/google/status": {
      "get": {
        "tags": [
          "Integrations"
        ],
        "summary": "Get Google integration status",
        "description": "Check Google integration connection status.",
        "operationId": "getGoogleIntegrationStatus",
        "responses": {
          "200": {
            "description": "Integration status"
          }
        }
      },
      "delete": {
        "tags": [
          "Integrations"
        ],
        "summary": "Disconnect Google integration",
        "description": "Disconnect Google integration and revoke tokens.",
        "operationId": "disconnectGoogleIntegration",
        "responses": {
          "200": {
            "description": "Integration disconnected"
          }
        }
      }
    },
    "/api/tools/website-check": {
      "get": {
        "tags": [
          "Tools"
        ],
        "summary": "Website health check",
        "description": "Free tool to check website availability, response time, SSL, headers, and more. Rate limited to 10 requests/minute per IP.",
        "operationId": "websiteCheck",
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "URL to check (https:// prefix added if missing)"
          }
        ],
        "responses": {
          "200": {
            "description": "Website check results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "responseTime": {
                      "type": "integer"
                    },
                    "statusCode": {
                      "type": "integer"
                    },
                    "ssl": {
                      "type": "object"
                    },
                    "headers": {
                      "type": "object"
                    },
                    "dns": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/tools/ssl-check": {
      "get": {
        "tags": [
          "Tools"
        ],
        "summary": "SSL certificate check",
        "description": "Free tool to check SSL certificate validity, expiration, and chain details.",
        "operationId": "sslCheck",
        "security": [],
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Host name, optionally with an https:// prefix or a :port, for example `example.com` or `example.com:8443`."
          }
        ],
        "responses": {
          "200": {
            "description": "SSL certificate details"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/tools/dns-check": {
      "get": {
        "tags": [
          "Tools"
        ],
        "summary": "DNS lookup tool",
        "description": "Free tool to check DNS records (A, AAAA, MX, NS, TXT, CNAME, SOA).",
        "operationId": "dnsCheck",
        "security": [],
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "A",
                "AAAA",
                "MX",
                "CNAME",
                "TXT",
                "NS",
                "SOA",
                "ALL"
              ],
              "default": "ALL"
            },
            "description": "Record type. Case-insensitive."
          }
        ],
        "responses": {
          "200": {
            "description": "DNS records"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/tools/speed-test": {
      "get": {
        "tags": [
          "Tools"
        ],
        "summary": "Website speed test",
        "description": "Free tool to test website loading speed and performance metrics.",
        "operationId": "speedTest",
        "security": [],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Speed test results"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      }
    },
    "/api/reports/digest": {
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Reports"
        ],
        "summary": "Get digest report",
        "description": "Get the latest monitoring digest report for the organization.",
        "operationId": "getDigestReport",
        "responses": {
          "200": {
            "description": "Digest report"
          }
        }
      }
    },
    "/api/reports/generate": {
      "post": {
        "tags": [
          "Reports"
        ],
        "summary": "Generate report",
        "description": "Retired. Always returns 410 Gone; use `/api/reports/studio/generate` instead.",
        "operationId": "generateReport",
        "responses": {
          "410": {
            "description": "Retired. Use /api/reports/studio/generate.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      },
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Get report status",
        "description": "Retired. Always returns 410 Gone; use `/api/reports/studio/generate` instead.",
        "operationId": "getReportStatus",
        "responses": {
          "410": {
            "description": "Retired. Use /api/reports/studio/generate.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/analytics": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get analytics overview",
        "description": "Get monitoring analytics and statistics for the organization.",
        "operationId": "getAnalytics",
        "responses": {
          "200": {
            "description": "Analytics data"
          }
        }
      }
    },
    "/api/analytics/journeys": {
      "post": {
        "tags": [
          "Analytics"
        ],
        "summary": "Track journey event",
        "description": "Track a user journey event.",
        "operationId": "trackJourney",
        "security": [],
        "responses": {
          "200": {
            "description": "Event tracked"
          }
        }
      }
    },
    "/api/analytics/subscription-events": {
      "get": {
        "tags": [
          "Analytics"
        ],
        "summary": "Get subscription events",
        "description": "Get subscription lifecycle events for analytics.",
        "operationId": "getSubscriptionEvents",
        "responses": {
          "200": {
            "description": "Subscription events"
          }
        }
      },
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Analytics"
        ],
        "summary": "Track subscription event",
        "description": "Record a plan-change funnel event (UPGRADED, DOWNGRADED or REACTIVATED) from the signed-in app. Session only: API keys cannot use it. Payment, revenue and refund events and fields are recorded from billing and are refused here.",
        "operationId": "trackSubscriptionEvent",
        "responses": {
          "200": {
            "description": "Event tracked"
          }
        }
      }
    },
    "/api/notifications": {
      "get": {
        "tags": [
          "Notifications"
        ],
        "summary": "List in-app notifications",
        "description": "Get in-app notifications for the current user (bell icon).",
        "operationId": "listNotifications",
        "responses": {
          "200": {
            "description": "Notifications"
          }
        }
      },
      "patch": {
        "tags": [
          "Notifications"
        ],
        "summary": "Mark notifications as read",
        "description": "Mark one or more notifications as read.",
        "operationId": "markNotificationsRead",
        "responses": {
          "200": {
            "description": "Notifications marked as read"
          }
        }
      },
      "delete": {
        "tags": [
          "Notifications"
        ],
        "summary": "Delete notifications",
        "description": "Delete notifications.",
        "operationId": "deleteNotifications",
        "responses": {
          "200": {
            "description": "Notifications deleted"
          }
        }
      }
    },
    "/api/notifications/bulk-assign": {
      "post": {
        "tags": [
          "Notifications"
        ],
        "summary": "Bulk assign notifications",
        "description": "Bulk assign notification channels to monitors.",
        "operationId": "bulkAssignNotifications",
        "responses": {
          "200": {
            "description": "Assignments updated"
          }
        }
      }
    },
    "/api/user/profile": {
      "get": {
        "tags": [
          "User"
        ],
        "summary": "Get user profile",
        "description": "Get the current user's profile information.",
        "operationId": "getUserProfile",
        "responses": {
          "200": {
            "description": "User profile"
          }
        }
      },
      "put": {
        "tags": [
          "User"
        ],
        "summary": "Update user profile",
        "description": "Update the current user's profile (name, avatar, etc.).",
        "operationId": "updateUserProfile",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "avatar": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Profile updated"
          }
        }
      }
    },
    "/api/user/profile/avatar": {
      "post": {
        "tags": [
          "User"
        ],
        "summary": "Upload avatar",
        "description": "Upload a new avatar image for the current user. Accepts JPEG, PNG, WebP, or GIF up to 2MB. Replaces any existing avatar.",
        "operationId": "uploadAvatar",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Avatar image file (JPEG, PNG, WebP, or GIF, max 2MB)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Avatar uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "avatar": {
                      "type": "string",
                      "description": "URL path to the uploaded avatar"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid file type or file too large"
          },
          "401": {
            "description": "Not authenticated"
          },
          "503": {
            "description": "Database unavailable"
          }
        }
      },
      "delete": {
        "tags": [
          "User"
        ],
        "summary": "Delete avatar",
        "description": "Remove the current user's avatar image and reset to default.",
        "operationId": "deleteAvatar",
        "responses": {
          "200": {
            "description": "Avatar deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not authenticated"
          },
          "503": {
            "description": "Database unavailable"
          }
        }
      }
    },
    "/api/user/delete-account": {
      "post": {
        "tags": [
          "User"
        ],
        "summary": "Delete account",
        "description": "Permanently delete the user's account.",
        "operationId": "deleteAccount",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Account deleted"
          }
        }
      }
    },
    "/api/user/digest-preferences": {
      "get": {
        "tags": [
          "User"
        ],
        "summary": "Get digest preferences",
        "description": "Get the user's email digest preferences.",
        "operationId": "getDigestPreferences",
        "responses": {
          "200": {
            "description": "Digest preferences"
          }
        }
      },
      "put": {
        "tags": [
          "User"
        ],
        "summary": "Update digest preferences",
        "description": "Update email digest frequency and settings.",
        "operationId": "updateDigestPreferences",
        "responses": {
          "200": {
            "description": "Preferences updated"
          }
        }
      }
    },
    "/api/user/organizations/switch": {
      "post": {
        "tags": [
          "User"
        ],
        "summary": "Switch organization",
        "description": "Switch the active organization for the current session.",
        "operationId": "switchOrganization",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "organizationId"
                ],
                "properties": {
                  "organizationId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Organization switched"
          }
        },
        "security": [
          {
            "SessionAuth": []
          }
        ]
      }
    },
    "/api/api-keys": {
      "get": {
        "tags": [
          "API Keys"
        ],
        "summary": "List API keys",
        "description": "Get all API keys for the organization.",
        "operationId": "listApiKeys",
        "responses": {
          "200": {
            "description": "List of API keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiKey"
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "API Keys"
        ],
        "summary": "Create API key",
        "description": "Generate a new API key for programmatic access. Requires a paid plan: API access comes with every paid plan (Solo, Starter, Business, Agency and custom Enterprise plans).",
        "operationId": "createApiKey",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "scopes"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Required. At least one scope, e.g. monitors:read, servers:write, * etc."
                  },
                  "expiresAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO 8601 expiry timestamp (preferred). Takes precedence over expiresIn."
                  },
                  "expiresIn": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Legacy alternative to expiresAt: number of days until the key expires. Used only when expiresAt is omitted."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created (key shown only once)",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiKey"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string",
                          "description": "The actual API key value (shown only once)"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "API Keys"
        ],
        "summary": "Delete API key",
        "description": "Revoke an API key.",
        "operationId": "deleteApiKey",
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "API key deleted"
          }
        }
      }
    },
    "/api/chat": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Send chat message",
        "description": "Send a message to the AI chat support system.",
        "operationId": "sendChatMessage",
        "responses": {
          "200": {
            "description": "AI response"
          }
        }
      },
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Get chat messages",
        "description": "Get chat message history.",
        "operationId": "getChatMessages",
        "responses": {
          "200": {
            "description": "Chat messages"
          }
        }
      }
    },
    "/api/chat/sessions": {
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "List chat sessions",
        "description": "Get all chat sessions for the current user.",
        "operationId": "listChatSessions",
        "responses": {
          "200": {
            "description": "Chat sessions"
          }
        }
      },
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Create chat session",
        "description": "Start a new chat session.",
        "operationId": "createChatSession",
        "responses": {
          "201": {
            "description": "Session created"
          }
        }
      }
    },
    "/api/chat/sessions/{id}": {
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Get chat session",
        "description": "Get a specific chat session with messages.",
        "operationId": "getChatSession",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Chat session with messages"
          }
        }
      },
      "patch": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Update chat session",
        "description": "Update a chat session (e.g., rename).",
        "operationId": "updateChatSession",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session updated"
          }
        }
      },
      "delete": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Delete chat session",
        "description": "Delete a chat session and its messages.",
        "operationId": "deleteChatSession",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Session deleted"
          }
        }
      }
    },
    "/api/chat/sessions/{id}/convert-to-ticket": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Convert chat to support ticket",
        "description": "Convert a chat session into a support ticket for human follow-up.",
        "operationId": "convertChatToTicket",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Ticket created"
          }
        }
      }
    },
    "/api/chat/feedback": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Submit chat feedback",
        "description": "Submit feedback (thumbs up/down) for a chat response.",
        "operationId": "submitChatFeedback",
        "responses": {
          "200": {
            "description": "Feedback submitted"
          }
        }
      }
    },
    "/api/chat/upload": {
      "post": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Chat"
        ],
        "summary": "Upload chat attachment",
        "description": "Upload an image or file attachment for a chat message.",
        "operationId": "uploadChatAttachment",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "File uploaded"
          }
        }
      }
    },
    "/api/onboarding/status": {
      "get": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Get onboarding status",
        "description": "Get the user's onboarding progress.",
        "operationId": "getOnboardingStatus",
        "responses": {
          "200": {
            "description": "Onboarding status"
          }
        }
      }
    },
    "/api/onboarding/select-plan": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Select plan during onboarding",
        "description": "Select a plan as part of the onboarding flow.",
        "operationId": "selectOnboardingPlan",
        "responses": {
          "200": {
            "description": "Plan selected"
          }
        }
      }
    },
    "/api/onboarding/auto-setup": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Auto-setup during onboarding",
        "description": "Automatically create a monitor from a URL during onboarding.",
        "operationId": "autoSetup",
        "responses": {
          "200": {
            "description": "Auto-setup complete"
          }
        }
      }
    },
    "/api/onboarding/start-no-card-trial": {
      "post": {
        "tags": [
          "Onboarding"
        ],
        "summary": "Start no-card trial",
        "description": "Start a 7-day free trial on the selected plan without requiring a credit card. Requires write access. The organization must not already have an active subscription or Paddle subscription.",
        "operationId": "startNoCardTrial",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "solo",
                      "starter",
                      "business",
                      "agency"
                    ],
                    "description": "Plan to trial (legacy names 'enterprise'/'professional' are accepted)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Trial started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "plan": {
                      "type": "string"
                    },
                    "trialEndsAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid plan name"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Email address not verified yet (code EMAIL_VERIFICATION_REQUIRED), or no write access"
          },
          "404": {
            "description": "Organization not found"
          },
          "409": {
            "description": "Organization already has an active subscription or trial, or the free trial was already used by this person or workspace (code TRIAL_ALREADY_USED)"
          }
        }
      }
    },
    "/api/settings/deduplication": {
      "get": {
        "tags": [
          "Settings"
        ],
        "summary": "Get deduplication settings",
        "description": "Get alert deduplication settings.",
        "operationId": "getDeduplicationSettings",
        "responses": {
          "200": {
            "description": "Deduplication settings"
          }
        }
      },
      "put": {
        "tags": [
          "Settings"
        ],
        "summary": "Update deduplication settings",
        "description": "Update alert deduplication configuration.",
        "operationId": "updateDeduplicationSettings",
        "responses": {
          "200": {
            "description": "Settings updated"
          }
        }
      }
    },
    "/api/settings/deduplication/stats": {
      "get": {
        "tags": [
          "Settings"
        ],
        "summary": "Get deduplication stats",
        "description": "Get statistics on how many alerts have been deduplicated.",
        "operationId": "getDeduplicationStats",
        "responses": {
          "200": {
            "description": "Deduplication statistics"
          }
        }
      }
    },
    "/api/settings/reports": {
      "get": {
        "tags": [
          "Settings"
        ],
        "summary": "Get report settings",
        "description": "Get scheduled report configuration.",
        "operationId": "getReportSettings",
        "responses": {
          "200": {
            "description": "Report settings"
          }
        }
      },
      "put": {
        "tags": [
          "Settings"
        ],
        "summary": "Update report settings",
        "description": "Update scheduled report configuration (frequency, recipients).",
        "operationId": "updateReportSettings",
        "responses": {
          "200": {
            "description": "Settings updated"
          }
        }
      }
    },
    "/api/settings/reports/test": {
      "post": {
        "tags": [
          "Settings"
        ],
        "summary": "Send test report",
        "description": "Retired. Always returns 410 Gone; use `/api/reports/studio/send-me` instead.",
        "operationId": "sendTestReport",
        "responses": {
          "410": {
            "description": "Retired. Use /api/reports/studio/send-me.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "replacement": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "deprecated": true
      }
    },
    "/api/ai/insights": {
      "get": {
        "security": [
          {
            "SessionAuth": []
          }
        ],
        "tags": [
          "Analytics"
        ],
        "summary": "Get AI insights",
        "description": "Get AI-generated insights about monitoring data and trends.",
        "operationId": "getAiInsights",
        "responses": {
          "200": {
            "description": "AI insights"
          }
        }
      }
    },
    "/api/support/tickets": {
      "post": {
        "tags": [
          "Chat"
        ],
        "summary": "Create support ticket",
        "description": "Create a support ticket directly.",
        "operationId": "createSupportTicket",
        "responses": {
          "201": {
            "description": "Ticket created"
          }
        }
      },
      "get": {
        "tags": [
          "Chat"
        ],
        "summary": "List support tickets",
        "description": "Get all support tickets for the current user.",
        "operationId": "listSupportTickets",
        "responses": {
          "200": {
            "description": "Support tickets"
          }
        }
      }
    },
    "/api/contact": {
      "post": {
        "tags": [
          "Public"
        ],
        "summary": "Submit contact form",
        "description": "Submit a contact form message. No authentication required.",
        "operationId": "submitContactForm",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "email",
                  "message"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "subject": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message sent"
          }
        }
      }
    },
    "/api/public/announcement": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Get active announcement",
        "description": "Returns the currently active site announcement (promotional banners, maintenance notices, etc.). Cached for 60 seconds. No authentication required. Falls back to environment-based discount config if no database announcement is active.",
        "operationId": "getPublicAnnouncement",
        "security": [],
        "parameters": [
          {
            "name": "context",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "public",
                "dashboard",
                "checkout"
              ],
              "default": "public"
            },
            "description": "Filter announcements by display context"
          }
        ],
        "responses": {
          "200": {
            "description": "Active announcement or null",
            "content": {
              "application/json": {
                "schema": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "PROMO",
                        "MAINTENANCE",
                        "INFO",
                        "WARNING"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "active": {
                      "type": "boolean"
                    },
                    "discountId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "discountPercent": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "bgColor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "textColor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "icon": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "showOnPublic": {
                      "type": "boolean"
                    },
                    "showOnDashboard": {
                      "type": "boolean"
                    },
                    "showOnCheckout": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/public/stats": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Get public statistics",
        "description": "Get public platform statistics (total monitors, checks performed, etc.).",
        "operationId": "getPublicStats",
        "security": [],
        "responses": {
          "200": {
            "description": "Public stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "available": {
                      "type": "boolean",
                      "description": "False when counts could not be read. Clients should omit unavailable or zero proof counts."
                    },
                    "totalMonitors": {
                      "type": "integer"
                    },
                    "totalChecks": {
                      "type": "integer"
                    },
                    "totalUsers": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/public/blog": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "List blog posts",
        "description": "Get published blog posts with pagination.",
        "operationId": "listBlogPosts",
        "security": [],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 10
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Blog posts"
          }
        }
      }
    },
    "/api/public/blog/{slug}": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Get blog post",
        "description": "Get a single blog post by slug.",
        "operationId": "getBlogPost",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Blog post"
          },
          "404": {
            "description": "Post not found"
          }
        }
      }
    },
    "/api/public/blog/{slug}/view": {
      "post": {
        "tags": [
          "Public"
        ],
        "summary": "Track blog post view",
        "description": "Increment the view count for a blog post.",
        "operationId": "trackBlogView",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "View tracked"
          }
        }
      }
    },
    "/api/public/status/{slug}": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Get public status page",
        "description": "Get a public status page by slug (no auth required).",
        "operationId": "getPublicStatusPage",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Public status page data"
          },
          "404": {
            "description": "Status page not found"
          }
        }
      }
    },
    "/api/public/status/{slug}/badge": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Get status badge",
        "description": "Get an SVG status badge for embedding in README files or websites.",
        "operationId": "getStatusBadge",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "SVG badge",
            "content": {
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/status/{slug}/subscribe": {
      "post": {
        "tags": [
          "Public"
        ],
        "summary": "Subscribe to status updates",
        "description": "Subscribe an email address to status page updates.",
        "operationId": "subscribeToStatusPage",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscribed (verification email sent)"
          }
        }
      },
      "delete": {
        "tags": [
          "Public"
        ],
        "summary": "Unsubscribe from status updates",
        "description": "Unsubscribe from status page updates.",
        "operationId": "unsubscribeFromStatusPage",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unsubscribed"
          }
        }
      }
    },
    "/api/public/status/{slug}/verify": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Verify status page subscription",
        "description": "Verify email subscription to a status page using the verification token.",
        "operationId": "verifyStatusSubscription",
        "security": [],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription verified"
          }
        }
      }
    },
    "/api/public/resolve-domain": {
      "get": {
        "tags": [
          "Public"
        ],
        "summary": "Resolve custom domain",
        "description": "Resolve a custom domain to find the associated status page.",
        "operationId": "resolveCustomDomain",
        "security": [],
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Resolved status page"
          },
          "404": {
            "description": "Domain not found"
          }
        }
      }
    },
    "/api/webhooks/paddle": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Paddle webhook",
        "description": "Incoming webhook handler for Paddle billing events (subscription created, updated, cancelled, payment).",
        "operationId": "paddleWebhook",
        "security": [],
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "/api/webhooks/whatsapp": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "WhatsApp webhook verification",
        "description": "Webhook verification endpoint for WhatsApp Business API.",
        "operationId": "whatsappWebhookVerify",
        "security": [],
        "responses": {
          "200": {
            "description": "Verification challenge response"
          }
        }
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "WhatsApp webhook",
        "description": "Incoming webhook handler for WhatsApp message events.",
        "operationId": "whatsappWebhook",
        "security": [],
        "responses": {
          "200": {
            "description": "Webhook processed"
          }
        }
      }
    },
    "/api/content-proxy": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Content proxy",
        "description": "Proxy content through the server to avoid CORS issues.",
        "operationId": "contentProxy",
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proxied content"
          }
        }
      }
    },
    "/api/verify-domain": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Verify domain ownership",
        "description": "Verify domain ownership via DNS TXT record lookup.",
        "operationId": "verifyDomain",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Domain verification result"
          }
        },
        "security": []
      }
    },
    "/api/client-error": {
      "post": {
        "tags": [
          "System"
        ],
        "summary": "Report client error",
        "description": "Report a client-side JavaScript error for logging.",
        "operationId": "reportClientError",
        "security": [],
        "responses": {
          "200": {
            "description": "Error logged"
          }
        }
      }
    },
    "/api/indexnow": {
      "post": {
        "tags": [
          "System"
        ],
        "summary": "IndexNow submission",
        "description": "Submit URLs to IndexNow for search engine indexing. Internal: requires the deployment shared secret, not a session or API key.",
        "operationId": "submitIndexNow",
        "responses": {
          "200": {
            "description": "URLs submitted"
          }
        },
        "security": []
      }
    },
    "/api/revalidate": {
      "post": {
        "tags": [
          "System"
        ],
        "summary": "Revalidate cache",
        "description": "Refresh cached pages for specific paths. Internal: requires the deployment shared secret, not a session or API key.",
        "operationId": "revalidateCache",
        "responses": {
          "200": {
            "description": "Cache revalidated"
          }
        },
        "security": []
      }
    },
    "/api/email-tracking/open/{messageId}": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Track email open",
        "description": "Tracking pixel endpoint for email open tracking.",
        "operationId": "trackEmailOpen",
        "security": [],
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "1x1 transparent pixel"
          }
        }
      }
    },
    "/api/email-tracking/click/{messageId}": {
      "get": {
        "tags": [
          "System"
        ],
        "summary": "Track email click",
        "description": "Redirect endpoint for email click tracking.",
        "operationId": "trackEmailClick",
        "security": [],
        "parameters": [
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirect to target URL"
          }
        }
      }
    },
    "/api/tools/domain-expiry": {
      "post": {
        "tags": [
          "Free Tools"
        ],
        "summary": "Domain expiry lookup (free, no auth)",
        "description": "Looks up a domain registration's expiry date, registrar, registration date, and status locks via registry RDAP. Public endpoint, rate limited to 10 requests per 10 minutes per IP. Input must be a bare registrable domain (no scheme, path, or subdomain).",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain"
                ],
                "properties": {
                  "domain": {
                    "type": "string",
                    "example": "example.com"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lookup result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domain": {
                      "type": "string"
                    },
                    "outcome": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "unsupported_tld",
                        "lookup_failed",
                        "not_found"
                      ]
                    },
                    "expiresAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "daysRemaining": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "registeredAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "registrar": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "domainStatuses": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "checkedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Input is not a bare registrable domain"
          },
          "429": {
            "description": "Rate limit exceeded (10 per 10 minutes per IP)"
          }
        }
      }
    },
    "/api/monitors/{id}/restore": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Restore a deleted monitor",
        "description": "Restore a monitor deleted within the last 24 hours, including its full check and incident history. Returns 410 when the restore window has passed.",
        "operationId": "restoreMonitor",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Monitor restored"
          },
          "404": {
            "description": "Monitor not found or not deleted"
          },
          "410": {
            "description": "Restore window has passed"
          }
        }
      }
    },
    "/api/monitors/deleted": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "List recently deleted monitors",
        "description": "Monitors deleted within the last 24 hours that can still be restored.",
        "operationId": "listDeletedMonitors",
        "responses": {
          "200": {
            "description": "List of restorable monitors"
          }
        }
      }
    },
    "/api/dependencies": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "List service dependencies",
        "description": "The catalog of third-party services you can monitor as dependencies, each with your workspace's monitor for it when you have one. API keys need the `monitors:read` scope.",
        "operationId": "listServiceDependencies",
        "responses": {
          "200": {
            "description": "Service catalog with your monitors",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceDependencyCatalog"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key"
          },
          "403": {
            "description": "The key lacks the monitors:read scope, or the plan does not include API access"
          },
          "500": {
            "description": "The catalog could not be loaded"
          }
        }
      }
    },
    "/api/dependencies/{slug}": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Get a service's provider status",
        "description": "What the service's provider reports on its own status page right now: overall state, each part (component), open incidents and scheduled maintenance. When the provider publishes no feed we can read, `available` is false and `statusUrl` still links to its public status page. API keys need the `monitors:read` scope.",
        "operationId": "getServiceDependencyStatus",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Service slug from GET /api/dependencies, e.g. `github`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Provider status, or why there is none",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ServiceDependencyStatus"
                    },
                    {
                      "$ref": "#/components/schemas/ServiceDependencyNoFeed"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key"
          },
          "403": {
            "description": "The key lacks the monitors:read scope, or the plan does not include API access"
          },
          "404": {
            "description": "Unknown service"
          },
          "502": {
            "description": "The provider's status feed is not answering right now"
          }
        }
      },
      "patch": {
        "tags": [
          "Monitors"
        ],
        "summary": "Choose the parts a service monitor follows",
        "description": "Sets which of the provider's parts (components) your monitor for this service alerts on. An empty list follows everything the provider reports. The monitor must exist (start monitoring the service first) and the provider must publish a status feed. Requires a role that can change monitors; API keys need the `monitors:write` scope.",
        "operationId": "updateServiceDependencyComponents",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Service slug from GET /api/dependencies, e.g. `github`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateServiceDependencyComponentsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Saved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateServiceDependencyComponentsResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid selection, or the service has no status feed to follow parts of"
          },
          "401": {
            "description": "Not signed in, or no valid API key"
          },
          "403": {
            "description": "Your role cannot change monitors, the key lacks the monitors:write scope, or the plan does not include API access"
          },
          "404": {
            "description": "Unknown service, or no monitor for it in this workspace yet"
          },
          "409": {
            "description": "One or more of the parts are no longer listed by the provider"
          },
          "502": {
            "description": "The provider's status feed is not answering right now"
          }
        }
      }
    },
    "/api/monitoring/regions": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "Check region availability",
        "description": "Whether this workspace can use the Asia Pacific (ASIA) region for uptime `locations` and `visualRegion`. Use ASIA only when both `apac.available` and `apacAllowed` are true; otherwise monitor create and update with ASIA return 400 `REGION_UNAVAILABLE` (or 403 `LOCATION_RESTRICTED` when the plan excludes it). EU and US do not depend on this check. API key scope: `monitors:read`.",
        "operationId": "getMonitoringRegions",
        "responses": {
          "200": {
            "description": "Region availability",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apac",
                    "apacAllowed"
                  ],
                  "properties": {
                    "apac": {
                      "type": "object",
                      "required": [
                        "available",
                        "label"
                      ],
                      "properties": {
                        "available": {
                          "type": "boolean",
                          "description": "A healthy Asia Pacific check node is online."
                        },
                        "label": {
                          "type": "string",
                          "description": "Display name of the region."
                        }
                      }
                    },
                    "apacAllowed": {
                      "type": "boolean",
                      "description": "This workspace is enabled for Asia Pacific and its plan allows the region."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "No organization membership, or an API key without `monitors:read`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/maintenance/{id}/cancel": {
      "post": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Cancel maintenance window",
        "description": "Cancel a window. For a repeating window, `action: \"skip-next\"` skips one occurrence (the next one, or `occurrence`) and `action: \"stop-repeating\"` turns it into a one-off; without an action the whole window is cancelled.",
        "operationId": "cancelMaintenanceWindow",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "skip-next",
                      "stop-repeating"
                    ]
                  },
                  "occurrence": {
                    "type": "string",
                    "format": "date-time",
                    "description": "With `skip-next`: the future occurrence start to skip."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No next occurrence to skip.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Maintenance window not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/incidents/{id}/updates": {
      "post": {
        "tags": [
          "Incidents"
        ],
        "summary": "Post incident update",
        "description": "Post a status update on an incident. It shows on the incident page and on every status page that shows this incident, and the incident status changes to match. It is sent at once to the incident's alert channels and status page subscribers, unless `notify` is false. Needs the owner or admin role.",
        "operationId": "createIncidentUpdate",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "status",
                  "message"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "INVESTIGATING",
                      "IDENTIFIED",
                      "MONITORING",
                      "RESOLVED",
                      "POSTMORTEM"
                    ],
                    "description": "Case-insensitive."
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000
                  },
                  "notify": {
                    "type": "boolean",
                    "default": true,
                    "description": "true (the default) sends the update at once to the incident's alert channels and to the subscribers of its status pages. false posts it without notifying anyone; it still shows on the incident timeline and on the status page. PagerDuty, Opsgenie and Prometheus only receive an update that closes or reopens an alert a check opened."
                  },
                  "actionId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "A UUID you choose for this update. Posting again with the same actionId returns the update already posted (200) and sends nothing. An actionId already used on another incident returns 409."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "This actionId was already posted. Returns that update; nothing is posted or sent again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "notified": {
                      "type": "boolean",
                      "description": "false when the update was posted without notifying anyone."
                    },
                    "authorId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "author": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "email": {
                          "type": "string"
                        }
                      }
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "201": {
            "description": "Update posted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    },
                    "notified": {
                      "type": "boolean",
                      "description": "false when the update was posted without notifying anyone."
                    },
                    "authorId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "author": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "email": {
                          "type": "string"
                        }
                      }
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid status or message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Not an owner or admin, or an API key without `incidents:write`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Incident not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The actionId was already used on another incident.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/mute": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Mute a monitor's alerts",
        "description": "Stops this monitor's alerts from going to any notification channel for the chosen duration. Checks keep running, incidents still open and close, alerts still appear in the dashboard, and possible-malware alerts are always sent; a new request replaces the current end time. Requires the Owner, Admin or Developer role; API keys need the `monitors:write` scope.",
        "operationId": "muteMonitorAlerts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MonitorAlertMuteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Muted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorAlertMuteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body is not JSON, or `durationMinutes` is not 60, 480, 1440 or 10080 (the response then lists `allowedDurationMinutes`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "allowedDurationMinutes": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer or Member role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Monitors"
        ],
        "summary": "Unmute a monitor's alerts",
        "description": "Ends the monitor's alert mute at once. Alerts held back during the mute are not sent afterwards; a problem that is still going alerts again at its next reminder. Succeeds when the monitor is not muted. Requires the Owner, Admin or Developer role; API keys need the `monitors:write` scope.",
        "operationId": "unmuteMonitorAlerts",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Unmuted (`alertsMutedUntil` is null)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorAlertMuteResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer or Member role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Service temporarily unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/resolve": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Match a monitor to your servers",
        "description": "Looks up the addresses the monitor's URL points to now (with origin addresses behind Cloudflare when a Cloudflare integration is connected), saves them on the monitor, and records matching servers as suggestions. Dismissed and manual links are never changed; automatic links can be confirmed, moved, or returned to a suggestion when the site's address changed. Takes no body. Any role except Viewer; API keys need the `monitors:write` scope.",
        "operationId": "resolveMonitorServers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lookup done",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorServerResolveResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/servers": {
      "get": {
        "tags": [
          "Monitors"
        ],
        "summary": "List servers linked to a monitor",
        "description": "Returns the servers confirmed as hosting this monitor's site, the automatic matches waiting for a decision, and the addresses from the last lookup. Dismissed links are not returned. API keys need the `monitors:read` scope.",
        "operationId": "listMonitorServers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Linked servers and suggestions",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorServerListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Link a server to a monitor",
        "description": "Records that the monitor's site runs on this server, as a confirmed manual link. An existing suggested or dismissed link to the same server becomes a confirmed manual link. Any role except Viewer; API keys need the `monitors:write` scope.",
        "operationId": "linkMonitorServer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "serverId"
                ],
                "properties": {
                  "serverId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "A server of your organization."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Linked",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorServerLink"
                }
              }
            }
          },
          "400": {
            "description": "`serverId` is missing or not a string",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Monitor not found, or server not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/{id}/servers/{msId}": {
      "patch": {
        "tags": [
          "Monitors"
        ],
        "summary": "Confirm or dismiss a server link",
        "description": "`confirm` makes the link confirmed (source `auto`); `dismiss` hides it, and the server is not suggested again for this monitor. Any role except Viewer; API keys need the `monitors:write` scope.",
        "operationId": "updateMonitorServerLink",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "msId",
            "in": "path",
            "required": true,
            "description": "ID of the monitor-to-server link (the `id` of an entry in `linked` or `suggestions` from GET /api/monitors/{id}/servers).",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "confirm",
                      "dismiss"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorServerLink"
                }
              }
            }
          },
          "400": {
            "description": "`action` is not \"confirm\" or \"dismiss\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Link not found for this monitor in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Monitors"
        ],
        "summary": "Remove a server link",
        "description": "Deletes the link. Unlike dismissing, a later lookup can suggest the same server again. Any role except Viewer; API keys need the `monitors:write` scope.",
        "operationId": "unlinkMonitorServer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Monitor ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "msId",
            "in": "path",
            "required": true,
            "description": "ID of the monitor-to-server link (the `id` of an entry in `linked` or `suggestions` from GET /api/monitors/{id}/servers).",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Link not found for this monitor in your organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/bulk-delete": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Delete a batch of monitors",
        "description": "Deletes up to 2,000 monitors, each through the same rules as DELETE /api/monitors/{id}: checks stop at once and each monitor can be restored for 24 hours. Monitors that cannot be deleted are reported in `skipped` with the reason, so the request can partly succeed. Requires the Owner or Admin role; API keys need the `monitors:write` scope. Limited to 30 requests per minute per organization.",
        "operationId": "bulkRemoveMonitors",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "description": "Monitor IDs. Duplicates are collapsed; IDs that are not monitors of your organization are reported in `skipped` with the reason \"Monitor not found.\"",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 2000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed. `unchanged` is always empty here.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Body is missing or not JSON, or fails validation. `details` holds `formErrors` and `fieldErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Developer, Member or Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 requests in a minute to this bulk route for the organization",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "ISO time the window resets.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkRateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/bulk-enabled": {
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Pause or resume a batch of monitors",
        "description": "Pauses or resumes up to 2,000 monitors, each through PUT /api/monitors/{id}. Resumes run one at a time in the order sent, so when the plan allowance runs out the remaining monitors are reported in `skipped` with the reason. Monitors already in the requested state are listed in `unchanged`. Requires the Owner, Admin or Developer role; API keys need the `monitors:write` scope. Limited to 30 requests per minute per organization.",
        "operationId": "bulkSetMonitorsEnabled",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds",
                  "enabled"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "description": "Monitor IDs. Duplicates are collapsed; IDs that are not monitors of your organization are reported in `skipped` with the reason \"Monitor not found.\"",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 2000
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "`false` pauses, `true` resumes."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed. Each monitor is reported in exactly one of `updated`, `skipped` or `unchanged`, in the order the IDs were sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Body is missing or not JSON, or fails validation. `details` holds `formErrors` and `fieldErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer or Member role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 requests in a minute to this bulk route for the organization",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "ISO time the window resets.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkRateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/bulk-settings": {
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Change settings on a batch of monitors",
        "description": "Applies the same settings to up to 2,000 monitors, each through PUT /api/monitors/{id}, so plan limits (check interval floor, regions, visual and certificate features) apply per monitor. A monitor the plan or its type does not allow is reported in `skipped` with the reason. Requires the Owner, Admin or Developer role; API keys need the `monitors:write` scope. Limited to 30 requests per minute per organization.",
        "operationId": "bulkUpdateMonitorSettings",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds",
                  "settings"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "description": "Monitor IDs. Duplicates are collapsed; IDs that are not monitors of your organization are reported in `skipped` with the reason \"Monitor not found.\"",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 2000
                  },
                  "settings": {
                    "$ref": "#/components/schemas/MonitorBulkSettings"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed. `unchanged` is always empty here.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Body is missing or not JSON, or fails validation. `details` holds `formErrors` and `fieldErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer or Member role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 requests in a minute to this bulk route for the organization",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "ISO time the window resets.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkRateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/bulk-tags": {
      "put": {
        "tags": [
          "Monitors"
        ],
        "summary": "Add tags to a batch of monitors",
        "description": "Adds tags to up to 2,000 monitors. Each monitor keeps its existing tags in order with new ones after, without duplicates. A monitor that would end up with more than 20 tags is skipped; one that already has every tag is listed in `unchanged`. Requires the Owner, Admin or Developer role; API keys need the `monitors:write` scope. Limited to 30 requests per minute per organization.",
        "operationId": "bulkAddMonitorTags",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds",
                  "add"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "description": "Monitor IDs. Duplicates are collapsed; IDs that are not monitors of your organization are reported in `skipped` with the reason \"Monitor not found.\"",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "minItems": 1,
                    "maxItems": 2000
                  },
                  "add": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 30,
                      "description": "Trimmed before the length check."
                    },
                    "description": "Tags to add."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed. Each monitor is reported in exactly one of `updated`, `skipped` or `unchanged`, in the order the IDs were sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkResult"
                }
              }
            }
          },
          "400": {
            "description": "Body is missing or not JSON, or fails validation. `details` holds `formErrors` and `fieldErrors`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer or Member role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "More than 30 requests in a minute to this bulk route for the organization",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Reset": {
                "description": "ISO time the window resets.",
                "schema": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkRateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/api/monitors/bulk-link-server": {
      "post": {
        "tags": [
          "Monitors"
        ],
        "summary": "Link a batch of monitors to a server",
        "description": "Records up to 2,000 monitors as running on one server, as confirmed manual links. IDs that are not monitors of your organization are ignored without being reported. Any role except Viewer; API keys need the `monitors:write` scope. Not rate limited.",
        "operationId": "bulkLinkMonitorsToServer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds",
                  "serverId"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 2000,
                    "items": {
                      "type": "string",
                      "minLength": 1
                    }
                  },
                  "serverId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "A server of your organization."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Processed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitorBulkLinkServerResponse"
                }
              }
            }
          },
          "400": {
            "description": "Body is missing or not JSON, or fails validation (`error` is \"Invalid request\" and `details` is the list of validation issues)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "details": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Viewer role, paused seat (code `SEAT_PAUSED_BY_PLAN`), missing or invalid CSRF token, no membership in the organization, or the API key lacks the `monitors:write` scope or plan API access",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Server not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/incidents/{id}/context": {
      "get": {
        "tags": [
          "Incidents"
        ],
        "summary": "Get incident detail context",
        "description": "Returns everything the incident detail view shows in one read: plain-language headline and summary, the checks around the incident, per-region results, the monitor's settings, suggested fixes, alerts sent, status page preview, updates and related incidents. API keys need the `incidents:read` scope. The response is not cached.",
        "operationId": "getIncidentContext",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Incident ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "tz",
            "in": "query",
            "required": false,
            "description": "IANA time zone (for example `Europe/Berlin`) that decides where \"today\" starts for `uptimeToday`. Missing or unknown zones use UTC.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Incident context",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IncidentContext"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "No membership in the organization, or the incident belongs to another organization you are a member of (`error` is `wrong_org`, with that organization's ID and name so the client can switch)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "organizationId": {
                      "type": "string"
                    },
                    "organizationName": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Incident not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Database unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/alerts/deliveries": {
      "get": {
        "tags": [
          "Alerts"
        ],
        "summary": "List alert deliveries",
        "description": "Lists the alerts sent for your monitors, grouped per alert event with the outcome for each channel, plus a seven-day summary. 50 events per page. Results may be up to 15 seconds old. API keys need the `alerts:read` scope.",
        "operationId": "listAlertDeliveries",
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "`today` starts at 00:00 UTC today; `7d` (the default, also used for any other value) starts six days before the current time.",
            "schema": {
              "type": "string",
              "enum": [
                "today",
                "7d"
              ],
              "default": "7d"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "`not_sent` returns only channel deliveries that were not sent; any other value returns all.",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "not_sent"
              ],
              "default": "all"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number. Values below 1 or not numeric are treated as 1.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Delivery log",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AlertDeliveryLog"
                }
              }
            }
          },
          "401": {
            "description": "Not signed in, or no valid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/groups": {
      "get": {
        "tags": [
          "Status Pages"
        ],
        "summary": "List status page groups",
        "description": "List the component groups on a status page in display order, each with the number of monitors assigned to it.",
        "operationId": "listStatusPageGroups",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Groups on the status page, ordered by `order` ascending",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "groups": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/StatusPageGroup"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "_count": {
                                "type": "object",
                                "properties": {
                                  "monitors": {
                                    "type": "integer",
                                    "description": "Number of linked monitors assigned to this group"
                                  }
                                }
                              }
                            }
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Create status page group",
        "description": "Create a component group at the end of the status page's group order. When `tagRule` is set the group auto-syncs: every monitor in the organization carrying that tag is linked to the page (if not already) and placed in the group. Requires the Owner, Admin or Developer role.",
        "operationId": "createStatusPageGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "Group name (trimmed). Must be unique within the status page."
                  },
                  "tagRule": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 100,
                    "description": "Monitor tag that drives automatic group membership (trimmed). Empty or null creates a manual group with auto-sync off."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Group created and, when it has a tag rule, synced",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "group": {
                      "$ref": "#/components/schemas/StatusPageGroup"
                    },
                    "sync": {
                      "$ref": "#/components/schemas/StatusPageGroupSyncResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid name or tag rule (`Enter a valid group name and tag`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`), or the CSRF token is missing or invalid for a cookie session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A group with this name already exists on this status page (`A group with this name already exists on this status page.`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/groups/reorder": {
      "put": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Reorder status page groups",
        "description": "Replace the complete group order in one step. `groupIds` must list every group currently on the status page exactly once; the first ID gets order 1. Requires the Owner, Admin or Developer role.",
        "operationId": "reorderStatusPageGroups",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "groupIds"
                ],
                "properties": {
                  "groupIds": {
                    "type": "array",
                    "maxItems": 200,
                    "uniqueItems": true,
                    "description": "Every group ID on the status page, in the new display order",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order saved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "groupIds": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body or duplicate IDs (`Invalid group order`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`), or the CSRF token is missing or invalid for a cookie session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The submitted IDs do not match the page's current groups (`The groups changed. Refresh before reordering.`). Also returned when the status page does not exist in the caller's organization and the list is not empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/groups/{groupId}": {
      "patch": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Update status page group",
        "description": "Rename a group or change its tag rule, then re-run the group's tag sync. Sending `tagRule` turns auto-sync on when the value is non-empty and off when it is empty or null; omitting it leaves auto-sync unchanged. Requires the Owner, Admin or Developer role.",
        "operationId": "updateStatusPageGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "Group ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80,
                    "description": "New group name (trimmed). Must be unique within the status page."
                  },
                  "tagRule": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 100,
                    "description": "Monitor tag that drives automatic group membership (trimmed). Empty or null turns auto-sync off."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Group updated and synced",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "group": {
                      "$ref": "#/components/schemas/StatusPageGroup"
                    },
                    "sync": {
                      "$ref": "#/components/schemas/StatusPageGroupSyncResult"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body (`Invalid group settings`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`), or the CSRF token is missing or invalid for a cookie session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Group not found on this status page in the caller's organization (`Status page group not found`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "A group with this name already exists on this status page (`A group with this name already exists on this status page.`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Delete status page group",
        "description": "Delete a group. Monitors in the group stay on the status page and become ungrouped. Requires the Owner, Admin or Developer role.",
        "operationId": "deleteStatusPageGroup",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "groupId",
            "in": "path",
            "required": true,
            "description": "Group ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Group deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Status page group deleted"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`), or the CSRF token is missing or invalid for a cookie session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Group not found on this status page in the caller's organization (`Status page group not found`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/servers": {
      "get": {
        "tags": [
          "Status Pages"
        ],
        "summary": "List servers on status page",
        "description": "List the servers shown on a status page in display order, with their current status, latest metrics and per-page display options.",
        "operationId": "listStatusPageServers",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Servers on the status page, ordered by `order` ascending",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "servers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StatusPageServerListItem"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Add servers to status page",
        "description": "Add one server (`serverId`) or several (`serverIds`, which takes precedence when non-empty) to the end of the status page's server order. Servers outside the caller's organization are ignored and servers already on the page are skipped. Requires the Owner, Admin or Developer role.",
        "operationId": "addServerToStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Provide `serverId` or a non-empty `serverIds` array.",
                "properties": {
                  "serverId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "A single server to add"
                  },
                  "serverIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Servers to add in one request. Used instead of `serverId` when non-empty."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Servers added",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "2 server(s) added to status page"
                    },
                    "added": {
                      "type": "integer",
                      "description": "Number of requested servers found in the organization, including any that were already on the page and therefore skipped"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Neither `serverId` nor `serverIds` provided (`Server ID is required`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found, or none of the requested servers belong to the caller's organization (`No valid servers found`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/servers/{serverId}": {
      "patch": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Update status page server display",
        "description": "Change how a linked server appears on the status page. Fields with the wrong type are ignored. Requires the Owner, Admin or Developer role.",
        "operationId": "updateStatusPageServer",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "serverId",
            "in": "path",
            "required": true,
            "description": "Server ID (not the link ID)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "displayName": {
                    "type": "string",
                    "description": "Name shown on the status page. An empty string clears it so the server name is used."
                  },
                  "showMetrics": {
                    "type": "boolean",
                    "description": "Show CPU, memory and disk metrics on the status page"
                  },
                  "order": {
                    "type": "integer",
                    "description": "Display position"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Display options updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusPageServer": {
                      "$ref": "#/components/schemas/StatusPageServerLink"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request body is not valid JSON (`Invalid JSON body`) or is not a JSON object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found, or the server is not on this status page (`Server is not linked to this status page`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Remove server from status page",
        "description": "Remove a server from the status page and renumber the remaining servers from 1. The server itself is not deleted. Requires the Owner, Admin or Developer role.",
        "operationId": "removeServerFromStatusPage",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "serverId",
            "in": "path",
            "required": true,
            "description": "Server ID (not the link ID)",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Server removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string",
                      "example": "Server removed from status page"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found, or the server is not on this status page (`Server is not linked to this status page`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/monitors/reorder": {
      "put": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Reorder status page monitors",
        "description": "Replace the complete monitor order in one step. `monitorIds` must list every monitor currently linked to the status page exactly once; the first ID gets order 1. Group assignments are not changed. Requires the Owner, Admin or Developer role.",
        "operationId": "reorderStatusPageMonitors",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "monitorIds"
                ],
                "properties": {
                  "monitorIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 2000,
                    "uniqueItems": true,
                    "description": "Every monitor ID linked to the status page (monitor IDs, not link IDs), in the new display order",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Order saved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "monitorIds": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "uuid"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid body (`Invalid monitor order`) or duplicate IDs (`Monitor order contains duplicates`). Also returned when the request body is not valid JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Caller does not have the Owner, Admin or Developer role, the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`), or the CSRF token is missing or invalid for a cookie session",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "The submitted IDs do not match the monitors currently linked to the page (`The linked monitors changed. Refresh before reordering.`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/logo": {
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Upload status page logo",
        "description": "Upload the status page logo, or the dark-theme logo with `?variant=dark`, replacing the current one. Accepts PNG, JPEG, WebP, GIF or SVG up to 2 MB; SVG files are sanitized and must be well-formed. Requires the white-label feature (Agency plan) and the Owner or Admin role.",
        "operationId": "uploadStatusPageLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "in": "query",
            "required": false,
            "description": "`dark` sets the dark-theme logo. Any other value or no value sets the standard logo.",
            "schema": {
              "type": "string",
              "enum": [
                "dark"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Image file: PNG, JPEG, WebP, GIF or SVG, up to 2 MB. The file content must match its declared type."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Logo uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "url": {
                      "type": "string",
                      "description": "Site-relative URL of the stored logo",
                      "example": "/uploads/logos/example.png"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No file provided, unsupported type or size (`PNG, JPG, WebP, GIF or SVG, up to 2 MB.`), content that does not match its type, or an SVG that fails validation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The organization's plan does not include white-label branding (`Status page logos require the Agency plan.`), the caller is not an Owner or Admin, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Remove status page logo",
        "description": "Clear the status page logo, or the dark-theme logo with `?variant=dark`. Requires the white-label feature (Agency plan) and the Owner or Admin role.",
        "operationId": "deleteStatusPageLogo",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variant",
            "in": "query",
            "required": false,
            "description": "`dark` clears the dark-theme logo. Any other value or no value clears the standard logo.",
            "schema": {
              "type": "string",
              "enum": [
                "dark"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Logo removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The organization's plan does not include white-label branding (`Status page logos require the Agency plan.`), the caller is not an Owner or Admin, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/status-pages/{id}/favicon": {
      "post": {
        "tags": [
          "Status Pages"
        ],
        "summary": "Upload status page favicon",
        "description": "Upload the status page favicon, replacing the current one. Accepts PNG, JPEG, WebP or GIF up to 2 MB (SVG and ICO are not accepted). To clear the favicon, update the status page with `favicon: null`. Requires the white-label feature (Agency plan) and the Owner or Admin role.",
        "operationId": "uploadStatusPageFavicon",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Status page ID",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "Image file: PNG, JPEG, WebP or GIF, up to 2 MB. The file content must match its declared type."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Favicon uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "url": {
                      "type": "string",
                      "description": "Site-relative URL of the stored favicon",
                      "example": "/uploads/logos/example-favicon.png"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No file provided, unsupported type or size (`File must be a PNG, JPEG, WebP, or GIF under 2MB.`), or content that does not match its type (`File content does not match its type.`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "The organization's plan does not include white-label branding (`Status page logos require the Agency plan.`), the caller is not an Owner or Admin, or the seat is paused by the plan (code `SEAT_PAUSED_BY_PLAN`)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Status page not found in the caller's organization",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "SessionAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "session",
        "description": "Session cookie obtained from POST /api/auth/login"
      },
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key (vs_xxxxx). Can also be sent via X-API-Key header or api_key query parameter."
      }
    },
    "schemas": {
      "ServiceDependencyCatalog": {
        "type": "object",
        "required": [
          "services"
        ],
        "properties": {
          "services": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "slug",
                "name",
                "domain",
                "statusUrl",
                "monitor",
                "intelligence"
              ],
              "properties": {
                "slug": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "domain": {
                  "type": "string"
                },
                "statusUrl": {
                  "type": "string",
                  "format": "uri",
                  "description": "The service's public status page."
                },
                "statusSource": {
                  "type": "string",
                  "enum": [
                    "official",
                    "community",
                    "support"
                  ]
                },
                "description": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "searchVolume": {
                  "type": "number"
                },
                "monitor": {
                  "description": "Your workspace's monitor for this service; null when you do not monitor it.",
                  "oneOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "lastCheckedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "responseTime": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "componentIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Parts the monitor follows; empty follows everything."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "provider-status",
                            "endpoint"
                          ],
                          "description": "provider-status reads the provider's status feed; endpoint checks the service directly."
                        }
                      }
                    }
                  ]
                },
                "intelligence": {
                  "type": "object",
                  "properties": {
                    "available": {
                      "type": "boolean"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "official-feed",
                        "endpoint-only"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "ServiceDependencyStatus": {
        "type": "object",
        "required": [
          "available",
          "serviceName",
          "statusUrl",
          "status",
          "components",
          "incidents",
          "maintenance"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "const": true
          },
          "serviceName": {
            "type": "string",
            "description": "The service's name (the monitor itself is named \"<Service> dependency\")."
          },
          "statusUrl": {
            "type": "string",
            "format": "uri",
            "description": "The provider's public status page."
          },
          "source": {
            "type": "string",
            "enum": [
              "atlassian-statuspage"
            ]
          },
          "apiUrl": {
            "type": "string",
            "format": "uri",
            "description": "The feed this status was read from."
          },
          "status": {
            "type": "string",
            "enum": [
              "operational",
              "maintenance",
              "degraded",
              "partial_outage",
              "major_outage",
              "unknown"
            ]
          },
          "description": {
            "type": "string",
            "description": "The provider's own summary line."
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          },
          "components": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "operational",
                    "maintenance",
                    "degraded",
                    "partial_outage",
                    "major_outage",
                    "unknown"
                  ]
                },
                "groupId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "isGroup": {
                  "type": "boolean",
                  "description": "A group heading rather than a part; groups cannot be followed."
                }
              }
            }
          },
          "incidents": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "description": "The provider's own wording, e.g. investigating, identified, monitoring, scheduled, in_progress."
                },
                "impact": {
                  "type": "string"
                },
                "shortlink": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uri",
                  "description": "The event's own page; null when the provider gives none (link to `statusUrl` instead)."
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "componentIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Parts this event affects."
                }
              }
            }
          },
          "maintenance": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "description": "The provider's own wording, e.g. investigating, identified, monitoring, scheduled, in_progress."
                },
                "impact": {
                  "type": "string"
                },
                "shortlink": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uri",
                  "description": "The event's own page; null when the provider gives none (link to `statusUrl` instead)."
                },
                "updatedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "componentIds": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "Parts this event affects."
                },
                "scheduledFor": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "scheduledUntil": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "ServiceDependencyNoFeed": {
        "type": "object",
        "required": [
          "available",
          "serviceName",
          "statusUrl",
          "message"
        ],
        "properties": {
          "available": {
            "type": "boolean",
            "const": false
          },
          "serviceName": {
            "type": "string"
          },
          "statusUrl": {
            "type": "string",
            "format": "uri"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "UpdateServiceDependencyComponentsRequest": {
        "type": "object",
        "required": [
          "componentIds"
        ],
        "properties": {
          "componentIds": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Part ids from GET /api/dependencies/{slug} (not groups). Empty follows everything the provider reports."
          }
        }
      },
      "UpdateServiceDependencyComponentsResponse": {
        "type": "object",
        "properties": {
          "monitorId": {
            "type": "string"
          },
          "componentIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "monitor": {
            "type": "object",
            "description": "The monitor fields written by this save, for immediately updating the client cache.",
            "required": [
              "url",
              "type",
              "method",
              "expectedStatus",
              "serviceDependencyComponents",
              "apiConfig"
            ],
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              },
              "type": {
                "type": "string",
                "enum": [
                  "API"
                ]
              },
              "method": {
                "type": "string",
                "enum": [
                  "GET"
                ]
              },
              "expectedStatus": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "serviceDependencyComponents": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "apiConfig": {
                "type": "object",
                "additionalProperties": true
              }
            }
          },
          "mode": {
            "type": "string",
            "enum": [
              "provider-status"
            ]
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Readable message."
          },
          "code": {
            "type": "string",
            "description": "Stable machine-readable code when the endpoint sets one, for example `SCOPE_DENIED`, `REGION_UNAVAILABLE` or `LOCATION_RESTRICTED`."
          },
          "message": {
            "type": "string"
          },
          "details": {
            "description": "Validation details when available."
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "healthy",
              "unhealthy"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "uptime": {
            "type": "number"
          },
          "version": {
            "type": "string"
          },
          "services": {
            "type": "object",
            "properties": {
              "database": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "latency": {
                    "type": "number"
                  }
                }
              },
              "redis": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "latency": {
                    "type": "number"
                  }
                }
              },
              "worker": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "activeJobs": {
                    "type": "number"
                  }
                }
              }
            }
          }
        }
      },
      "LoginRequest": {
        "type": "object",
        "required": [
          "email",
          "password"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string"
          }
        }
      },
      "RegisterRequest": {
        "type": "object",
        "required": [
          "name",
          "email",
          "password",
          "acceptTerms"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "description": "Must contain uppercase, lowercase, and number"
          },
          "organizationName": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "acceptTerms": {
            "type": "boolean"
          }
        }
      },
      "AuthResponse": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "organization": {
            "$ref": "#/components/schemas/Organization"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "role": {
            "type": "string",
            "enum": [
              "OWNER",
              "ADMIN",
              "MEMBER",
              "VIEWER"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Organization": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "plan": {
            "type": "string",
            "enum": [
              "FREE",
              "STARTER",
              "BUSINESS",
              "AGENCY",
              "CUSTOM"
            ]
          },
          "monitorLimit": {
            "type": "integer",
            "description": "Effective organization-specific monitor allowance. CUSTOM organizations may exceed the standard Agency limit."
          }
        }
      },
      "MonitorType": {
        "type": "string",
        "enum": [
          "HTTP",
          "HTTPS",
          "TCP",
          "UDP",
          "DNS",
          "SSL",
          "PING",
          "PORT",
          "KEYWORD",
          "API",
          "GRAPHQL",
          "WEBSOCKET"
        ],
        "description": "Monitor types accepted when creating a monitor. Visual and content change detection are not separate types: turn them on with `visualEnabled` and `contentConfig` on an HTTP or HTTPS monitor."
      },
      "MonitorStatus": {
        "type": "string",
        "enum": [
          "OPERATIONAL",
          "DEGRADED",
          "PARTIAL_OUTAGE",
          "MAJOR_OUTAGE",
          "UI_CHANGED",
          "CONTENT_STALE",
          "CONTENT_CHANGED",
          "UNDER_MAINTENANCE",
          "UNKNOWN"
        ]
      },
      "MonitorResponseStatus": {
        "type": "string",
        "enum": [
          "operational",
          "degraded",
          "down",
          "maintenance",
          "ui-changed",
          "content-changed",
          "unknown"
        ]
      },
      "HTTPMethod": {
        "type": "string",
        "enum": [
          "GET",
          "POST",
          "PUT",
          "PATCH",
          "DELETE",
          "HEAD",
          "QUERY",
          "OPTIONS"
        ]
      },
      "PageSpeedFailure": {
        "type": [
          "object",
          "null"
        ],
        "description": "The latest failed test and consecutive failure count. Null after a successful test.",
        "required": [
          "at",
          "reason",
          "strategy",
          "consecutiveFailures"
        ],
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "reason": {
            "type": "string"
          },
          "strategy": {
            "type": "string",
            "enum": [
              "mobile",
              "desktop"
            ]
          },
          "consecutiveFailures": {
            "type": "integer",
            "minimum": 1,
            "description": "Consecutive failed test runs, including daily and manually requested tests."
          }
        }
      },
      "Monitor": {
        "type": "object",
        "properties": {
          "serviceDependencySlug": {
            "type": [
              "string",
              "null"
            ],
            "description": "For a monitor of a service you rely on: the service's slug (see GET /api/dependencies). Null for every other monitor."
          },
          "serviceDependencyComponents": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "For a service monitor, the provider parts its alerts follow; empty follows everything. Returned by GET /api/monitors/{id}; change it with PATCH /api/dependencies/{slug}."
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "type": {
            "type": "string",
            "description": "Monitor type in lower case, for example `https`, `api` or `keyword`.",
            "examples": [
              "https"
            ]
          },
          "status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MonitorStatus"
              },
              {
                "$ref": "#/components/schemas/MonitorResponseStatus"
              }
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "method": {
            "$ref": "#/components/schemas/HTTPMethod"
          },
          "checkInterval": {
            "type": "integer",
            "description": "Check interval in seconds"
          },
          "timeout": {
            "type": "integer",
            "description": "Timeout in milliseconds"
          },
          "uptime": {
            "type": "number",
            "description": "Uptime percentage"
          },
          "uptime30d": {
            "type": [
              "number",
              "null"
            ],
            "description": "Uptime percentage over the last 30 UTC days. Null when no rated checks are available."
          },
          "pageSpeedError": {
            "$ref": "#/components/schemas/PageSpeedFailure"
          },
          "lastCheckedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastResponseTime": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Most recent check latency in milliseconds. Null when the latest check has no latency."
          },
          "responseTime": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Rolling 24-hour successful-check average in milliseconds, falling back to the latest latency for new monitors."
          },
          "avgResponseTime24h": {
            "type": [
              "integer",
              "null"
            ]
          },
          "lastChecked": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CheckRegion"
            },
            "description": "Uptime check regions."
          },
          "regionChecks": {
            "type": "array",
            "description": "Latest authoritative check per configured canonical region. An empty array means no regional evidence is available; clients must fall back to aggregate latency rather than inventing waiting states.",
            "items": {
              "type": "object",
              "required": [
                "region",
                "status",
                "responseTime",
                "checkedAt"
              ],
              "properties": {
                "region": {
                  "type": "string",
                  "enum": [
                    "EU",
                    "US",
                    "ASIA"
                  ]
                },
                "status": {
                  "type": "string"
                },
                "responseTime": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "checkedAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "visualRegion": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "EU",
              "ASIA",
              null
            ],
            "description": "Screenshot region. Null uses Europe. ASIA requires a healthy registered node and a plan with access to that region. Changing the region starts a fresh baseline."
          },
          "visualEnabled": {
            "type": "boolean"
          },
          "visualWafBlockedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When visual (screenshot) checks were last turned away by the site's own bot protection. Null when screenshots are not blocked or visual checks are off. Uptime checks are not affected. Returned by the monitor list."
          },
          "visualWafVendor": {
            "type": [
              "string",
              "null"
            ],
            "description": "The bot protection product that blocked screenshots, when it was recognised (for example cloudflare or siteground). Null when unknown or not blocked. Returned by the monitor list."
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "domainExpiryEnabled": {
            "type": "boolean",
            "default": true,
            "description": "Domain registration expiry monitoring for this monitor's registrable domain. Available on every plan."
          },
          "domainAlertDays": {
            "type": "array",
            "items": {
              "type": "integer",
              "enum": [
                50,
                30,
                20,
                13,
                6,
                3,
                1
              ]
            },
            "default": [
              50,
              13,
              3,
              1
            ],
            "description": "Days-before-expiry alert tiers. The 50-day tier provides time to review registrar terms, transfer locks, and renewal options before expiry."
          },
          "domainExpiry": {
            "type": [
              "object",
              "null"
            ],
            "description": "Registration expiry summary for the monitor's registrable domain (null when the URL has no registrable domain, e.g. an IP address).",
            "properties": {
              "domain": {
                "type": "string"
              },
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "daysRemaining": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "registrar": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "state": {
                "type": "string",
                "enum": [
                  "pending",
                  "ok",
                  "unsupported_tld",
                  "lookup_failed",
                  "not_found"
                ]
              },
              "lastCheckedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "enabled": {
                "type": "boolean"
              }
            }
          },
          "otherAddress": {
            "$ref": "#/components/schemas/OtherAddress"
          },
          "checkOtherAddress": {
            "type": "boolean",
            "default": true,
            "description": "Check the website’s www or bare-domain twin every 15 minutes without using a site slot. Ignored for other monitor types."
          },
          "visualChange": {
            "type": [
              "object",
              "null"
            ],
            "description": "Returned by GET /api/monitors only: present for an enabled monitor whose status is `ui-changed`, otherwise null. The unreviewed page change: how much changed, since when, and the capture an approval would accept. `thumbUrl` is an authenticated preview that needs a browser session; API keys cannot load it.",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "visual_change"
                ]
              },
              "percent": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "incidentId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "screenshotId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "visualTargetId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "thumbUrl": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "since": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          }
        }
      },
      "CreateMonitorRequest": {
        "type": "object",
        "required": [
          "name",
          "url"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Display name."
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Address to check. HTTP, HTTPS, KEYWORD, API and GRAPHQL monitors take a full http:// or https:// address. TCP and PORT take host:port, UDP takes udp://host:port, WEBSOCKET takes ws:// or wss://, and PING, DNS and SSL take a host name. Spaces are not allowed."
          },
          "type": {
            "$ref": "#/components/schemas/MonitorType",
            "default": "HTTPS",
            "description": "Monitor type. Defaults to HTTPS."
          },
          "checkInterval": {
            "default": 300,
            "type": "integer",
            "minimum": 60,
            "maximum": 86400,
            "description": "Seconds between uptime checks. On create, a value below your plan minimum is raised to the minimum."
          },
          "timeout": {
            "default": 30000,
            "type": "integer",
            "minimum": 1000,
            "maximum": 120000,
            "description": "Request timeout in milliseconds."
          },
          "maxResponseTime": {
            "default": 5000,
            "type": "integer",
            "minimum": 100,
            "maximum": 60000,
            "description": "Responses slower than this many milliseconds count as slow."
          },
          "enabled": {
            "default": true,
            "type": "boolean",
            "description": "Whether the monitor is checked. Send false to pause it and true to resume it."
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 10000,
            "description": "Free-text notes."
          },
          "tags": {
            "default": [],
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Tags for grouping and filtering. Status page groups can follow tags."
          },
          "locations": {
            "default": [
              "EU"
            ],
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "EU",
                "US",
                "ASIA"
              ]
            },
            "description": "Uptime check regions: EU, US and ASIA. Only HTTP, HTTPS, KEYWORD, API and GRAPHQL monitors can use US or ASIA; other types run from EU and another region returns 400 `LOCATION_UNSUPPORTED_FOR_TYPE`. Unknown regions return 400 `INVALID_LOCATION`; a region outside your plan returns 403 `LOCATION_RESTRICTED`. Asia Pacific is enabled per workspace during its rollout; call GET /api/monitoring/regions first. When this workspace cannot use ASIA the request fails with 400 `REGION_UNAVAILABLE`. Older spellings such as eu-west-1 are accepted and stored as the region code."
          },
          "visualRegion": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "EU",
              "ASIA",
              null
            ],
            "description": "Where screenshots for visual checks are taken: EU (the default, stored as null) or ASIA. Asia Pacific is enabled per workspace during its rollout; call GET /api/monitoring/regions first. When this workspace cannot use ASIA the request fails with 400 `REGION_UNAVAILABLE`. Changing the region starts a fresh baseline."
          },
          "visualEnabled": {
            "type": "boolean",
            "description": "Visual change detection (screenshots). On create, when omitted, it is turned on for HTTP and HTTPS monitors on plans that include visual monitoring. Needs a plan with visual monitoring (403 `FEATURE_RESTRICTED`) and a free visual slot (403 `LIMIT_EXCEEDED`)."
          },
          "serviceDependencySlug": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 100,
            "description": "Create a service monitor for a provider from GET /api/dependencies. The catalog sets the address, so `url` can be any placeholder. Returns 409 `DEPENDENCY_EXISTS` when that service is already monitored."
          },
          "method": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "GET",
              "POST",
              "PUT",
              "PATCH",
              "DELETE",
              "HEAD",
              "QUERY",
              "OPTIONS",
              null
            ],
            "description": "HTTP method for HTTP-family monitors."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Request headers as name and value pairs (up to 16 KB)."
          },
          "body": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 65536,
            "description": "Request body for POST, PUT, PATCH and QUERY checks."
          },
          "expectedStatus": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Status codes that count as up."
          },
          "followRedirects": {
            "type": "boolean",
            "description": "Follow redirects."
          },
          "expectedBody": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 65536,
            "description": "Text the response must contain."
          },
          "authType": {
            "type": [
              "string",
              "null"
            ],
            "description": "Authentication for the checked address: none, basic, bearer or apikey."
          },
          "authConfig": {
            "type": "object",
            "additionalProperties": true,
            "description": "Credentials for `authType`, for example `{ \"username\": \"...\", \"password\": \"...\" }` or `{ \"token\": \"...\" }` (up to 8 KB)."
          },
          "sslCheck": {
            "type": "boolean",
            "description": "Certificate expiry and validity monitoring. Needs a plan with SSL monitoring."
          },
          "checkOtherAddress": {
            "type": "boolean",
            "default": true,
            "description": "Check the website's www or bare-domain twin every 15 minutes without using a site slot. Ignored for other monitor types."
          },
          "sslDaysBefore": {
            "type": "number",
            "description": "Older single reminder threshold in days. Prefer `sslAlertDays`."
          },
          "sslAlertDays": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Days before certificate expiry to send reminders."
          },
          "domainExpiryEnabled": {
            "type": "boolean",
            "default": true,
            "description": "Domain registration expiry monitoring for this monitor's registrable domain. Available on every plan. Defaults to true on create."
          },
          "domainAlertDays": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "integer",
              "enum": [
                50,
                30,
                20,
                13,
                6,
                3,
                1
              ]
            },
            "default": [
              50,
              13,
              3,
              1
            ],
            "description": "Days-before-expiry reminder tiers. Defaults to [50, 13, 3, 1] on create."
          },
          "alertThreshold": {
            "type": "number",
            "description": "Consecutive failed checks before an alert is sent."
          },
          "slowAlertThreshold": {
            "type": "number",
            "description": "Consecutive slow responses before a slow-response alert."
          },
          "alertDelay": {
            "type": "integer",
            "minimum": 0,
            "description": "Seconds to wait after the threshold is met before alerting."
          },
          "reportEnabled": {
            "type": "boolean",
            "description": "Scheduled client report email for this monitor. Needs the Business plan or higher (403)."
          },
          "reportEmail": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 320,
            "description": "Report recipient."
          },
          "reportFrequency": {
            "type": "string",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "both",
              "all"
            ],
            "description": "Report schedule."
          },
          "notificationRepeatInterval": {
            "default": 60,
            "type": "integer",
            "minimum": 0,
            "maximum": 1440,
            "description": "Minutes between repeat alerts while a problem continues. 0 sends one alert."
          },
          "performanceThresholds": {
            "type": "object",
            "properties": {
              "responseTime": {
                "type": "integer"
              },
              "ttfb": {
                "type": "integer"
              },
              "fcp": {
                "type": "integer"
              },
              "lcp": {
                "type": "integer"
              },
              "cls": {
                "type": "number"
              }
            },
            "description": "Performance budgets in milliseconds (`responseTime`, `ttfb`, `fcp`, `lcp`) and `cls`."
          },
          "visualConfig": {
            "type": "object",
            "additionalProperties": true,
            "description": "Visual check settings: `threshold` (percent of changed pixels that counts as a change), `checkInterval` (seconds, at least 900), `viewport` `{ width, height }`, `fullPage`, `excludeSelectors`, video and GIF handling, and `auth` for pages behind a login. Up to 16 KB."
          },
          "dnsEnabled": {
            "type": "boolean",
            "description": "DNS record change monitoring. Needs a plan with DNS monitoring."
          },
          "dnsRecords": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            },
            "description": "DNS record types to watch, as `{ \"A\": true, \"MX\": true }`."
          },
          "performanceEnabled": {
            "type": "boolean",
            "description": "Daily phone speed test. Needs a plan with performance monitoring."
          },
          "keywordConfig": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "mustContain": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "mustNotContain": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "caseSensitive": {
                "type": "boolean"
              }
            },
            "description": "Keyword checks on the response: `mustContain` and `mustNotContain` lists, `caseSensitive`, and `enabled`."
          },
          "freshnessConfig": {
            "type": "object",
            "additionalProperties": true,
            "description": "Content freshness check: alert when a date on the page is older than `maxAgeHours`."
          },
          "contentConfig": {
            "type": "object",
            "additionalProperties": true,
            "description": "Content change detection: `selectors` (CSS selectors to include or exclude), `jsRendering`, and optional `conditions`. Needs a plan with content monitoring."
          },
          "apiConfig": {
            "$ref": "#/components/schemas/ApiMonitorConfig",
            "description": "API and GRAPHQL monitors: response checks (`assertions`), `responseSlo`, `responseFormat`, response body storage and, for GRAPHQL, the `graphql` query."
          }
        }
      },
      "UpdateMonitorRequest": {
        "type": "object",
        "properties": {
          "domainExpiryEnabled": {
            "type": "boolean",
            "description": "Domain registration expiry monitoring for this monitor's registrable domain. Available on every plan. Defaults to true on create."
          },
          "domainAlertDays": {
            "type": "array",
            "items": {
              "type": "integer",
              "enum": [
                50,
                30,
                20,
                13,
                6,
                3,
                1
              ]
            },
            "description": "Days-before-expiry reminder tiers. An empty list keeps the domain watched without reminder emails."
          },
          "domainReminderSnoozedUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Snooze domain expiry reminders until this time (at most 35 days ahead). Null clears the snooze."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "description": "Free-text notes."
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Address to check. HTTP, HTTPS, KEYWORD, API and GRAPHQL monitors take a full http:// or https:// address. TCP and PORT take host:port, UDP takes udp://host:port, WEBSOCKET takes ws:// or wss://, and PING, DNS and SSL take a host name. Spaces are not allowed."
          },
          "type": {
            "type": "string",
            "enum": [
              "HTTP",
              "HTTPS",
              "TCP",
              "PING",
              "DNS",
              "SSL",
              "WEBSOCKET",
              "GRAPHQL"
            ],
            "description": "Change the monitor type. Only these types can be set on update."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether the monitor is checked. Send false to pause it and true to resume it."
          },
          "method": {
            "$ref": "#/components/schemas/HTTPMethod",
            "description": "HTTP method for HTTP-family monitors."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Request headers as name and value pairs (up to 16 KB). A JSON string is also accepted."
          },
          "body": {
            "type": [
              "string",
              "null"
            ],
            "description": "Request body for POST, PUT, PATCH and QUERY checks."
          },
          "timeout": {
            "type": "integer",
            "minimum": 1000,
            "maximum": 120000,
            "description": "Request timeout in milliseconds."
          },
          "checkInterval": {
            "type": "integer",
            "minimum": 30,
            "maximum": 86400,
            "description": "Seconds between uptime checks. On create, a value below your plan minimum is raised to the minimum."
          },
          "expectedStatus": {
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 100,
              "maximum": 599
            },
            "description": "Status codes that count as up."
          },
          "expectedBody": {
            "type": [
              "string",
              "null"
            ],
            "description": "Text the response must contain."
          },
          "maxResponseTime": {
            "type": "integer",
            "minimum": 100,
            "maximum": 30000,
            "description": "Responses slower than this many milliseconds count as slow."
          },
          "sslCheck": {
            "type": "boolean",
            "description": "Certificate expiry and validity monitoring. Needs a plan with SSL monitoring."
          },
          "checkOtherAddress": {
            "type": "boolean",
            "description": "Check the website's www or bare-domain twin every 15 minutes without using a site slot. Ignored for other monitor types."
          },
          "sslWarningDays": {
            "type": "integer",
            "minimum": 1,
            "maximum": 90,
            "description": "Days before certificate expiry when the certificate is reported as expiring."
          },
          "ignoreSslErrors": {
            "type": "boolean",
            "description": "Treat certificate errors on the checked address as up."
          },
          "authType": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "none",
              "basic",
              "bearer",
              "api-key",
              "apikey",
              null
            ],
            "description": "Authentication for the checked address: none, basic, bearer or apikey."
          },
          "authConfig": {
            "type": [
              "object",
              "null"
            ],
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "description": "Credentials for `authType`, for example `{ \"username\": \"...\", \"password\": \"...\" }` or `{ \"token\": \"...\" }` (up to 8 KB)."
          },
          "locations": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "EU",
                "US",
                "ASIA"
              ]
            },
            "description": "Uptime check regions: EU, US and ASIA. Only HTTP, HTTPS, KEYWORD, API and GRAPHQL monitors can use US or ASIA; other types run from EU and another region returns 400 `LOCATION_UNSUPPORTED_FOR_TYPE`. Unknown regions return 400 `INVALID_LOCATION`; a region outside your plan returns 403 `LOCATION_RESTRICTED`. Asia Pacific is enabled per workspace during its rollout; call GET /api/monitoring/regions first. When this workspace cannot use ASIA the request fails with 400 `REGION_UNAVAILABLE`. Older spellings such as eu-west-1 are accepted and stored as the region code."
          },
          "followRedirects": {
            "type": "boolean",
            "description": "Follow redirects."
          },
          "maxRedirects": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Tags for grouping and filtering. Status page groups can follow tags."
          },
          "visualRegion": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "EU",
              "ASIA",
              null
            ],
            "description": "Where screenshots for visual checks are taken: EU (the default, stored as null) or ASIA. Asia Pacific is enabled per workspace during its rollout; call GET /api/monitoring/regions first. When this workspace cannot use ASIA the request fails with 400 `REGION_UNAVAILABLE`. Changing the region starts a fresh baseline."
          },
          "visualEnabled": {
            "type": "boolean",
            "description": "Visual change detection (screenshots). On create, when omitted, it is turned on for HTTP and HTTPS monitors on plans that include visual monitoring. Needs a plan with visual monitoring (403 `FEATURE_RESTRICTED`) and a free visual slot (403 `LIMIT_EXCEEDED`)."
          },
          "performanceEnabled": {
            "type": "boolean",
            "description": "Daily phone speed test. Needs a plan with performance monitoring."
          },
          "visualConfig": {
            "type": "object",
            "properties": {
              "threshold": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "checkInterval": {
                "type": "integer",
                "minimum": 900,
                "maximum": 86400
              },
              "viewport": {
                "type": "object",
                "properties": {
                  "width": {
                    "type": "integer",
                    "minimum": 320,
                    "maximum": 3840
                  },
                  "height": {
                    "type": "integer",
                    "minimum": 240,
                    "maximum": 2160
                  }
                }
              },
              "fullPage": {
                "type": "boolean"
              },
              "pauseVideos": {
                "type": "boolean"
              },
              "hideVideoEmbeds": {
                "type": "boolean"
              },
              "hideGifs": {
                "type": "boolean"
              },
              "hashMismatchThreshold": {
                "type": "integer",
                "minimum": 0,
                "maximum": 10
              },
              "duplicateTolerance": {
                "type": "number",
                "minimum": 0,
                "maximum": 100
              },
              "excludeSelectors": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "auth": {
                "type": "object",
                "properties": {
                  "type": {
                    "default": "none",
                    "type": "string",
                    "enum": [
                      "none",
                      "basic",
                      "bearer",
                      "cookie",
                      "form"
                    ]
                  },
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string"
                  },
                  "token": {
                    "type": "string"
                  },
                  "headerName": {
                    "default": "Authorization",
                    "type": "string"
                  },
                  "headerPrefix": {
                    "default": "Bearer",
                    "type": "string"
                  },
                  "cookies": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "value": {
                          "type": "string"
                        },
                        "domain": {
                          "type": "string"
                        },
                        "path": {
                          "default": "/",
                          "type": "string"
                        }
                      },
                      "required": [
                        "name",
                        "value",
                        "domain"
                      ]
                    }
                  },
                  "formLogin": {
                    "type": "object",
                    "properties": {
                      "loginUrl": {
                        "type": "string",
                        "maxLength": 2048
                      },
                      "usernameSelector": {
                        "type": "string"
                      },
                      "usernameValue": {
                        "type": "string"
                      },
                      "passwordSelector": {
                        "type": "string"
                      },
                      "passwordValue": {
                        "type": "string"
                      },
                      "submitSelector": {
                        "type": "string"
                      },
                      "waitForNavigation": {
                        "default": true,
                        "type": "boolean"
                      },
                      "waitForSelector": {
                        "type": "string"
                      },
                      "waitForUrl": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "loginUrl",
                      "usernameSelector",
                      "usernameValue",
                      "passwordSelector",
                      "submitSelector"
                    ]
                  }
                }
              }
            },
            "additionalProperties": {},
            "description": "Visual check settings: `threshold` (percent of changed pixels that counts as a change), `checkInterval` (seconds, at least 900), `viewport` `{ width, height }`, `fullPage`, `excludeSelectors`, video and GIF handling, and `auth` for pages behind a login."
          },
          "keywordConfig": {
            "type": "object",
            "properties": {
              "enabled": {
                "default": false,
                "type": "boolean"
              },
              "mustContain": {
                "maxItems": 100,
                "type": "array",
                "items": {
                  "type": "string",
                  "maxLength": 500
                }
              },
              "mustNotContain": {
                "maxItems": 100,
                "type": "array",
                "items": {
                  "type": "string",
                  "maxLength": 500
                }
              },
              "caseSensitive": {
                "type": "boolean"
              }
            },
            "description": "Keyword checks on the response: `mustContain` and `mustNotContain` lists, `caseSensitive`, and `enabled`."
          },
          "apiConfig": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ApiMonitorConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "API and GRAPHQL monitors: response checks (`assertions`), `responseSlo`, `responseFormat`, response body storage and, for GRAPHQL, the `graphql` query. Replaces the stored value."
          },
          "contentConfig": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "selectors": {
                "maxItems": 100,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "css": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "label": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "include",
                        "exclude"
                      ]
                    }
                  },
                  "required": [
                    "css",
                    "label",
                    "type"
                  ]
                }
              },
              "jsRendering": {
                "type": "boolean"
              },
              "conditions": {
                "type": "object",
                "properties": {
                  "matchMode": {
                    "type": "string",
                    "enum": [
                      "all",
                      "any"
                    ]
                  },
                  "rules": {
                    "maxItems": 100,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "numeric",
                            "length"
                          ]
                        },
                        "op": {
                          "type": "string",
                          "maxLength": 50
                        },
                        "value": {
                          "anyOf": [
                            {
                              "type": "number"
                            },
                            {
                              "type": "string"
                            }
                          ]
                        },
                        "extract": {
                          "type": "string",
                          "maxLength": 500
                        },
                        "flags": {
                          "type": "string",
                          "maxLength": 20
                        }
                      },
                      "required": [
                        "type",
                        "op"
                      ]
                    }
                  }
                },
                "additionalProperties": {}
              }
            },
            "additionalProperties": {},
            "description": "Content change detection: `selectors` (CSS selectors to include or exclude), `jsRendering`, and optional `conditions`. Needs a plan with content monitoring."
          },
          "freshnessConfig": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "maxAgeHours": {
                "type": "number",
                "minimum": 0,
                "maximum": 8760
              },
              "selector": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 2000
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "dateFormat": {
                "type": "string",
                "maxLength": 50
              },
              "customPattern": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 500
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "timezone": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 100
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "additionalProperties": {},
            "description": "Content freshness check: alert when a date on the page is older than `maxAgeHours`."
          },
          "notificationChannelIds": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Alert channels for this monitor. Replaces the current list."
          },
          "dnsEnabled": {
            "type": "boolean",
            "description": "DNS record change monitoring. Needs a plan with DNS monitoring."
          },
          "dnsRecords": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "maxLength": 30
            },
            "additionalProperties": {
              "type": "boolean"
            },
            "description": "DNS record types to watch, as `{ \"A\": true, \"MX\": true }`."
          },
          "performanceThresholds": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "responseTime": {
                "type": "integer",
                "minimum": 100,
                "maximum": 120000
              },
              "ttfb": {
                "type": "integer",
                "minimum": 0,
                "maximum": 120000
              },
              "fcp": {
                "type": "integer",
                "minimum": 0,
                "maximum": 120000
              },
              "lcp": {
                "type": "integer",
                "minimum": 0,
                "maximum": 120000
              },
              "cls": {
                "type": "number",
                "minimum": 0,
                "maximum": 10
              }
            },
            "additionalProperties": false,
            "description": "Performance budgets in milliseconds (`responseTime`, `ttfb`, `fcp`, `lcp`) and `cls`."
          },
          "sslAlertDays": {
            "maxItems": 10,
            "type": "array",
            "items": {
              "type": "integer",
              "minimum": 1,
              "maximum": 365
            },
            "description": "Days before certificate expiry to send reminders."
          },
          "reportEnabled": {
            "type": "boolean",
            "description": "Scheduled client report email for this monitor. Needs the Business plan or higher (403)."
          },
          "reportEmail": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "description": "Report recipient. An empty string or null clears it."
          },
          "reportFrequency": {
            "type": "string",
            "enum": [
              "weekly",
              "biweekly",
              "monthly",
              "both",
              "all"
            ],
            "description": "Report schedule."
          },
          "reportIncludeCharts": {
            "type": "boolean",
            "description": "Include charts in the report."
          },
          "reportIncludeIncidents": {
            "type": "boolean",
            "description": "Include incidents in the report."
          },
          "alertThreshold": {
            "type": "integer",
            "minimum": 1,
            "description": "Consecutive failed checks before an alert is sent."
          },
          "alertDelay": {
            "type": "integer",
            "minimum": 0,
            "description": "Seconds to wait after the threshold is met before alerting."
          },
          "slowAlertThreshold": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Consecutive slow responses before a slow-response alert."
          },
          "notificationRepeatInterval": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1440,
            "description": "Minutes between repeat alerts while a problem continues. 0 sends one alert."
          },
          "expectedAssertions": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Optional, sent with `apiConfig`: the response checks your change was based on, exactly as you read them from this monitor. If the stored checks have changed since, nothing is saved and the request answers 409 with code `ASSERTIONS_CHANGED`. It cannot be combined with `enabled`, `visualEnabled` or `keywordConfig` (400); send those separately."
          }
        }
      },
      "MonitorListResponse": {
        "type": "object",
        "description": "Paginated monitor list envelope, returned only when the request sends `Accept: application/json` and a `page` query parameter. The default (unpaginated) response is a bare array of Monitor objects.",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Monitor"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          },
          "summary": {
            "$ref": "#/components/schemas/MonitorListSummary"
          }
        }
      },
      "MonitorListSummary": {
        "type": "object",
        "description": "Exact counts for the current scope/search/type/tags, independent of the selected status chip.",
        "required": [
          "total",
          "operational",
          "down",
          "degraded",
          "changed",
          "pending",
          "paused",
          "sites",
          "apis",
          "measured",
          "avgUptime"
        ],
        "properties": {
          "total": {
            "type": "integer"
          },
          "operational": {
            "type": "integer"
          },
          "down": {
            "type": "integer"
          },
          "degraded": {
            "type": "integer"
          },
          "changed": {
            "type": "integer"
          },
          "pending": {
            "type": "integer"
          },
          "paused": {
            "type": "integer"
          },
          "sites": {
            "type": "integer"
          },
          "apis": {
            "type": "integer"
          },
          "measured": {
            "type": "integer"
          },
          "avgUptime": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      },
      "CheckResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/MonitorStatus"
          },
          "responseTime": {
            "type": "integer"
          },
          "statusCode": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "UptimeResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "description": "Time-bucketed uptime data points.",
            "items": {
              "type": "object",
              "required": [
                "time",
                "uptime"
              ],
              "properties": {
                "time": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Start of the bucket (ISO 8601 UTC)."
                },
                "uptime": {
                  "type": "number",
                  "description": "Uptime percentage for this bucket (0-100)."
                }
              },
              "additionalProperties": true
            }
          },
          "regions": {
            "type": "array",
            "description": "Region codes included in the result set.",
            "items": {
              "type": "string"
            }
          },
          "meta": {
            "type": "object",
            "description": "Query metadata describing how the response was assembled.",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "preset",
                  "custom"
                ],
                "description": "Whether a preset window or a custom from/to range was used."
              },
              "granularity": {
                "type": "string",
                "enum": [
                  "minute",
                  "hour",
                  "day",
                  "week"
                ],
                "description": "Bucket size used for the returned data points."
              },
              "bucketSeconds": {
                "type": "integer",
                "description": "Duration of each bucket in seconds."
              },
              "from": {
                "type": "string",
                "format": "date-time",
                "description": "Effective start of the window (ISO 8601 UTC)."
              },
              "to": {
                "type": "string",
                "format": "date-time",
                "description": "Effective end of the window (ISO 8601 UTC)."
              },
              "clampedFrom": {
                "type": "boolean",
                "description": "True when the requested `from` was earlier than the oldest available data and was clamped forward."
              },
              "source": {
                "type": "string",
                "enum": [
                  "raw",
                  "daily",
                  "mixed"
                ],
                "description": "Storage tier the data was read from."
              }
            }
          }
        }
      },
      "ResponseTimeResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "description": "Time-bucketed response-time data points.",
            "items": {
              "type": "object",
              "required": [
                "time",
                "responseTime"
              ],
              "properties": {
                "time": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Start of the bucket (ISO 8601 UTC)."
                },
                "responseTime": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "description": "Average response time for this bucket in milliseconds. Null when the bucket had no checks (e.g. monitor paused or no data in that window)."
                }
              },
              "additionalProperties": true
            }
          },
          "regions": {
            "type": "array",
            "description": "Region codes included in the result set.",
            "items": {
              "type": "string"
            }
          },
          "meta": {
            "type": "object",
            "description": "Query metadata describing how the response was assembled.",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "preset",
                  "custom"
                ],
                "description": "Whether a preset window or a custom from/to range was used."
              },
              "granularity": {
                "type": "string",
                "enum": [
                  "minute",
                  "hour",
                  "day",
                  "week"
                ],
                "description": "Bucket size used for the returned data points."
              },
              "bucketSeconds": {
                "type": "integer",
                "description": "Duration of each bucket in seconds."
              },
              "from": {
                "type": "string",
                "format": "date-time",
                "description": "Effective start of the window (ISO 8601 UTC)."
              },
              "to": {
                "type": "string",
                "format": "date-time",
                "description": "Effective end of the window (ISO 8601 UTC)."
              },
              "clampedFrom": {
                "type": "boolean",
                "description": "True when the requested `from` was earlier than the oldest available data and was clamped forward."
              },
              "source": {
                "type": "string",
                "enum": [
                  "raw",
                  "daily",
                  "mixed"
                ],
                "description": "Storage tier the data was read from."
              }
            }
          }
        }
      },
      "VisualDataResponse": {
        "type": "object",
        "properties": {
          "baseline": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string"
              },
              "capturedAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "latest": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string"
              },
              "capturedAt": {
                "type": "string",
                "format": "date-time"
              },
              "diffPercentage": {
                "type": "number"
              }
            }
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        }
      },
      "Server": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "hostname": {
            "type": "string"
          },
          "ipAddress": {
            "type": "string"
          },
          "os": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "ONLINE",
              "OFFLINE",
              "UNKNOWN"
            ]
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "cpuUsage": {
            "type": "number"
          },
          "memoryUsage": {
            "type": "number"
          },
          "diskUsage": {
            "type": "number"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ServerListResponse": {
        "type": "object",
        "properties": {
          "servers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Server"
            }
          }
        }
      },
      "ServerMetricsResponse": {
        "type": "object",
        "properties": {
          "metrics": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "timestamp": {
                  "type": "string",
                  "format": "date-time"
                },
                "cpu": {
                  "type": "number"
                },
                "memory": {
                  "type": "number"
                },
                "disk": {
                  "type": "number"
                },
                "networkIn": {
                  "type": "number"
                },
                "networkOut": {
                  "type": "number"
                }
              }
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "avgCpu": {
                "type": "number"
              },
              "avgMemory": {
                "type": "number"
              },
              "avgDisk": {
                "type": "number"
              },
              "maxCpu": {
                "type": "number"
              },
              "maxMemory": {
                "type": "number"
              }
            }
          }
        }
      },
      "ServerAlertListResponse": {
        "type": "object",
        "properties": {
          "alerts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "SERVER_ALERT",
                    "SERVER_OFFLINE",
                    "SERVER_RECOVERY"
                  ]
                },
                "severity": {
                  "type": "string",
                  "enum": [
                    "INFO",
                    "WARNING",
                    "CRITICAL"
                  ]
                },
                "message": {
                  "type": "string"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "total": {
            "type": "integer"
          }
        }
      },
      "Alert": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "enum": [
              "OPEN",
              "ACKNOWLEDGED",
              "RESOLVED"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "INFO",
              "WARNING",
              "CRITICAL"
            ]
          },
          "message": {
            "type": "string"
          },
          "monitorId": {
            "type": "string",
            "format": "uuid"
          },
          "acknowledgedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "AlertListResponse": {
        "type": "object",
        "properties": {
          "alerts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Alert"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "AlertRule": {
        "type": "object",
        "description": "An alert rule. Rules watch one monitor and evaluate response time or uptime conditions on its checks.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "organizationId": {
            "type": "string",
            "format": "uuid"
          },
          "monitorId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "The monitor this rule watches. Older rules without a monitor never run (supported: false)."
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "conditions": {
            "description": "The conditions as stored: one condition object or a list that must all be true. See CreateAlertRuleRequest for the accepted shapes. Rules saved earlier with other condition types are returned as stored, with supported: false."
          },
          "severity": {
            "type": "string",
            "enum": [
              "INFO",
              "WARNING",
              "CRITICAL"
            ]
          },
          "threshold": {
            "type": "integer"
          },
          "window": {
            "type": "integer",
            "description": "Seconds."
          },
          "cooldownMinutes": {
            "type": "integer",
            "description": "Minimum minutes between two notifications from this rule."
          },
          "scheduleStart": {
            "type": [
              "string",
              "null"
            ],
            "description": "24h HH:MM. With scheduleEnd, the rule only alerts inside this window."
          },
          "scheduleEnd": {
            "type": [
              "string",
              "null"
            ],
            "description": "24h HH:MM."
          },
          "timezone": {
            "type": "string",
            "description": "IANA timezone for the schedule window."
          },
          "supported": {
            "type": "boolean",
            "description": "False when the rule can never run: it has no monitor, or a condition alert rules do not evaluate. Unsupported rules are never evaluated."
          },
          "unsupportedReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why the rule is not supported, in plain words. Null when supported."
          },
          "monitor": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "notificationChannels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "enabled": {
                  "type": "boolean"
                }
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "conditions",
          "enabled",
          "supported",
          "unsupportedReason"
        ]
      },
      "AlertRuleResponse": {
        "type": "object",
        "properties": {
          "alertRule": {
            "$ref": "#/components/schemas/AlertRule"
          }
        }
      },
      "CreateAlertRuleRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "monitorId": {
            "default": null,
            "anyOf": [
              {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              {
                "type": "null"
              }
            ]
          },
          "conditions": {
            "anyOf": [
              {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "response_time"
                      },
                      "threshold": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Response time in milliseconds to compare each successful check against."
                      },
                      "operator": {
                        "default": "gt",
                        "type": "string",
                        "enum": [
                          "gt",
                          "gte",
                          "lt",
                          "lte",
                          "eq"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "threshold"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "uptime"
                      },
                      "threshold": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100,
                        "description": "Uptime percentage to compare the monitor against."
                      },
                      "operator": {
                        "default": "lt",
                        "type": "string",
                        "enum": [
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "threshold"
                    ]
                  }
                ]
              },
              {
                "minItems": 1,
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "response_time"
                        },
                        "threshold": {
                          "type": "number",
                          "exclusiveMinimum": 0,
                          "description": "Response time in milliseconds to compare each successful check against."
                        },
                        "operator": {
                          "default": "gt",
                          "type": "string",
                          "enum": [
                            "gt",
                            "gte",
                            "lt",
                            "lte",
                            "eq"
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "threshold"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "uptime"
                        },
                        "threshold": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Uptime percentage to compare the monitor against."
                        },
                        "operator": {
                          "default": "lt",
                          "type": "string",
                          "enum": [
                            "gt",
                            "gte",
                            "lt",
                            "lte"
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "threshold"
                      ]
                    }
                  ]
                }
              }
            ],
            "description": "A response time or uptime condition, or a list of them that must all be true. Down alerts, repeated failures and SSL expiry are sent by the built-in alerts, so rules do not accept them."
          },
          "severity": {
            "default": "WARNING",
            "type": "string",
            "enum": [
              "INFO",
              "WARNING",
              "CRITICAL"
            ]
          },
          "cooldownMinutes": {
            "default": 5,
            "type": "number",
            "exclusiveMinimum": 0
          },
          "notificationChannelIds": {
            "default": [],
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "enabled": {
            "default": true,
            "type": "boolean"
          },
          "scheduleStart": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
              },
              {
                "type": "null"
              }
            ]
          },
          "scheduleEnd": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
              },
              {
                "type": "null"
              }
            ]
          },
          "timezone": {
            "default": "UTC",
            "type": "string"
          }
        },
        "required": [
          "name",
          "conditions"
        ]
      },
      "UpdateAlertRuleRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "monitorId": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              {
                "type": "null"
              }
            ]
          },
          "conditions": {
            "anyOf": [
              {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "response_time"
                      },
                      "threshold": {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "description": "Response time in milliseconds to compare each successful check against."
                      },
                      "operator": {
                        "default": "gt",
                        "type": "string",
                        "enum": [
                          "gt",
                          "gte",
                          "lt",
                          "lte",
                          "eq"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "threshold"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "uptime"
                      },
                      "threshold": {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100,
                        "description": "Uptime percentage to compare the monitor against."
                      },
                      "operator": {
                        "default": "lt",
                        "type": "string",
                        "enum": [
                          "gt",
                          "gte",
                          "lt",
                          "lte"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "threshold"
                    ]
                  }
                ]
              },
              {
                "minItems": 1,
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "response_time"
                        },
                        "threshold": {
                          "type": "number",
                          "exclusiveMinimum": 0,
                          "description": "Response time in milliseconds to compare each successful check against."
                        },
                        "operator": {
                          "default": "gt",
                          "type": "string",
                          "enum": [
                            "gt",
                            "gte",
                            "lt",
                            "lte",
                            "eq"
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "threshold"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "uptime"
                        },
                        "threshold": {
                          "type": "number",
                          "minimum": 0,
                          "maximum": 100,
                          "description": "Uptime percentage to compare the monitor against."
                        },
                        "operator": {
                          "default": "lt",
                          "type": "string",
                          "enum": [
                            "gt",
                            "gte",
                            "lt",
                            "lte"
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "threshold"
                      ]
                    }
                  ]
                }
              }
            ],
            "description": "A response time or uptime condition, or a list of them that must all be true. Down alerts, repeated failures and SSL expiry are sent by the built-in alerts, so rules do not accept them."
          },
          "severity": {
            "type": "string",
            "enum": [
              "INFO",
              "WARNING",
              "CRITICAL"
            ]
          },
          "cooldownMinutes": {
            "type": "number",
            "exclusiveMinimum": 0
          },
          "notificationChannelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          "enabled": {
            "type": "boolean"
          },
          "scheduleStart": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
              },
              {
                "type": "null"
              }
            ]
          },
          "scheduleEnd": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
              },
              {
                "type": "null"
              }
            ]
          },
          "timezone": {
            "type": "string"
          }
        }
      },
      "AlertRuleConditionNotSupportedResponse": {
        "type": "object",
        "description": "Returned with 400 when a request uses status_change, consecutive_failures or ssl_expiry. Those are covered by the built-in alerts sent to the notification channels linked to each monitor.",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "const": "ALERT_CONDITION_NOT_SUPPORTED"
          },
          "unsupportedConditions": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "status_change",
                "consecutive_failures",
                "ssl_expiry"
              ]
            }
          }
        }
      },
      "AlertRuleListResponse": {
        "type": "object",
        "properties": {
          "alertRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AlertRule"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          }
        }
      },
      "NotificationChannel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "EMAIL",
              "SLACK",
              "PAGERDUTY",
              "WEBHOOK",
              "SMS",
              "DISCORD",
              "TEAMS",
              "WHATSAPP",
              "TELEGRAM",
              "OPSGENIE",
              "PROMETHEUS",
              "PUSH"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "config": {
            "type": "object",
            "description": "Channel-specific configuration"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Webhook notifications include other_address_failing and other_address_recovery events. Their additive metadata fields are described by OtherAddressWebhookMetadata."
      },
      "CreateNotificationChannelRequest": {
        "type": "object",
        "required": [
          "name",
          "type",
          "config"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100
          },
          "type": {
            "type": "string",
            "enum": [
              "EMAIL",
              "SLACK",
              "DISCORD",
              "TEAMS",
              "PAGERDUTY",
              "OPSGENIE",
              "WEBHOOK",
              "WHATSAPP",
              "TELEGRAM",
              "PROMETHEUS",
              "PUSH"
            ]
          },
          "enabled": {
            "type": "boolean",
            "default": true
          },
          "config": {
            "type": "object",
            "additionalProperties": true,
            "description": "Channel settings. EMAIL: `{ recipients: [email] }`. SLACK, DISCORD, TEAMS: `{ webhookUrl }`. PAGERDUTY: `{ integrationKey }`. OPSGENIE: `{ apiKey }`. WEBHOOK: `{ url, method?, headers?, secret?, payloadTemplate? }`. TELEGRAM: `{ botToken, chatId }`. WHATSAPP: `{ phoneNumbers, phoneNumberId, accessToken }`. PROMETHEUS: `{ alertmanagerUrl, basicAuth?, labels? }`. PUSH: `{ subscriptions }`."
          },
          "alertTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "DOWNTIME",
                "SLOW_RESPONSE",
                "VISUAL",
                "PERFORMANCE",
                "SSL",
                "DNS",
                "DOMAIN",
                "CONTENT"
              ]
            },
            "default": [],
            "description": "Alert kinds this channel receives. Empty means all."
          },
          "isDefault": {
            "type": "boolean",
            "default": false,
            "description": "Use this channel for monitors that have no channels of their own."
          }
        }
      },
      "Incident": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "investigating",
              "identified",
              "monitoring",
              "resolved",
              "postmortem"
            ]
          },
          "severity": {
            "type": "string",
            "enum": [
              "critical",
              "high",
              "medium",
              "low",
              "info"
            ]
          },
          "monitorId": {
            "type": "string",
            "format": "uuid"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string",
            "description": "First 8 characters of the key for identification"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          },
          "hasPrevious": {
            "type": "boolean"
          }
        }
      },
      "OtherAddress": {
        "type": [
          "object",
          "null"
        ],
        "description": "The www or bare-domain twin, independent of primary uptime. Null when disabled or ineligible. All plans include it.",
        "properties": {
          "host": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "enum": [
              "PENDING",
              "WORKING",
              "FAILING",
              "NOT_SET_UP",
              "BLOCKED"
            ]
          },
          "cause": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "NO_RESPONSE",
              "CONNECTION_REFUSED",
              "CERTIFICATE_HOST_MISMATCH",
              "CERTIFICATE_PROBLEM",
              "SECURE_CONNECTION_FAILED",
              "ERROR_PAGE",
              "DNS_RECORD_REMOVED",
              "REDIRECT_DNS_FAILED",
              "CHECKER_BLOCKED",
              "CHECKER_RATE_LIMITED",
              null
            ]
          },
          "since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "checkedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "redirectsTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "incidentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "statusCode": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "host",
          "state",
          "cause",
          "since",
          "checkedAt",
          "redirectsTo",
          "incidentId",
          "statusCode"
        ]
      },
      "OtherAddressWebhookMetadata": {
        "type": "object",
        "description": "Additive metadata on other_address_failing and other_address_recovery webhook events. Existing payload fields keep their meaning.",
        "properties": {
          "otherAddressHost": {
            "type": "string"
          },
          "otherAddressCause": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "NO_RESPONSE",
              "CONNECTION_REFUSED",
              "CERTIFICATE_HOST_MISMATCH",
              "CERTIFICATE_PROBLEM",
              "SECURE_CONNECTION_FAILED",
              "ERROR_PAGE",
              "DNS_RECORD_REMOVED",
              "REDIRECT_DNS_FAILED",
              "CHECKER_BLOCKED",
              "CHECKER_RATE_LIMITED",
              null
            ]
          },
          "statusCode": {
            "type": [
              "integer",
              "null"
            ]
          },
          "description": {
            "type": "string"
          }
        }
      },
      "StoredMonitorType": {
        "type": "string",
        "enum": [
          "HTTP",
          "HTTPS",
          "TCP",
          "UDP",
          "DNS",
          "SSL",
          "PING",
          "PORT",
          "KEYWORD",
          "API",
          "GRAPHQL",
          "WEBSOCKET",
          "GRPC",
          "SMTP",
          "IMAP",
          "FTP",
          "SSH",
          "DATABASE",
          "REDIS",
          "DOCKER",
          "KUBERNETES",
          "SYNTHETIC",
          "BROWSER",
          "VISUAL",
          "CONTENT"
        ],
        "description": "Every monitor type value a stored monitor can carry. Only the values in `MonitorType` can be created."
      },
      "CheckRegion": {
        "type": "string",
        "enum": [
          "EU",
          "US",
          "ASIA"
        ],
        "description": "Check region: EU (Europe), US (United States), ASIA (Asia Pacific)."
      },
      "ApiMonitorConfig": {
        "type": "object",
        "properties": {
          "assertions": {
            "maxItems": 100,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string",
                  "maxLength": 1024
                },
                "operator": {
                  "type": "string",
                  "enum": [
                    "equals",
                    "not_equals",
                    "contains",
                    "not_contains",
                    "exists",
                    "not_exists",
                    "greaterThan",
                    "lessThan",
                    "matches",
                    "type"
                  ]
                },
                "value": {
                  "anyOf": [
                    {
                      "type": "string",
                      "maxLength": 4096
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "valueType": {
                  "type": "string",
                  "enum": [
                    "string",
                    "number",
                    "boolean",
                    "null"
                  ]
                },
                "target": {
                  "default": "body",
                  "type": "string",
                  "enum": [
                    "body",
                    "header",
                    "status"
                  ]
                }
              },
              "required": [
                "path",
                "operator"
              ]
            }
          },
          "responseSlo": {
            "default": null,
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0,
                "maximum": 300000
              },
              {
                "type": "null"
              }
            ]
          },
          "responseFormat": {
            "default": "json",
            "type": "string",
            "enum": [
              "json",
              "text",
              "xml",
              "auto"
            ]
          },
          "saveResponseBody": {
            "default": true,
            "type": "boolean"
          },
          "maxResponseBodySize": {
            "default": 10240,
            "type": "integer",
            "minimum": 1024,
            "maximum": 51200
          },
          "graphql": {
            "type": "object",
            "properties": {
              "query": {
                "type": "string",
                "minLength": 1,
                "maxLength": 20480
              },
              "variables": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                }
              }
            },
            "required": [
              "query"
            ]
          }
        }
      },
      "MaintenanceWindow": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled",
              "in-progress",
              "completed",
              "cancelled"
            ]
          },
          "startTime": {
            "type": "string",
            "format": "date-time"
          },
          "endTime": {
            "type": "string",
            "format": "date-time"
          },
          "duration": {
            "type": "string",
            "description": "For example `1h 30m`."
          },
          "affectedServices": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Monitor names."
          },
          "affectedMonitorIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "recurring": {
            "type": "boolean"
          },
          "recurrenceRule": {
            "type": [
              "string",
              "null"
            ]
          },
          "recurrenceKind": {
            "type": "string",
            "enum": [
              "none",
              "day",
              "week",
              "month",
              "custom"
            ]
          },
          "nextOccurrence": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "startsAt": {
                "type": "string",
                "format": "date-time"
              },
              "endsAt": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "cancelledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "skippedOccurrences": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "date-time"
            }
          },
          "timezone": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateMaintenanceWindowRequest": {
        "type": "object",
        "required": [
          "title",
          "startTime",
          "endTime"
        ],
        "properties": {
          "title": {
            "type": "string",
            "description": "Window name shown on status pages."
          },
          "description": {
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "format": "date-time"
          },
          "endTime": {
            "type": "string",
            "format": "date-time",
            "description": "Must be after `startTime` and at most 90 days later. Alerts for the linked monitors are suppressed during the window."
          },
          "monitorIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Monitors covered by the window. IDs outside this workspace are ignored."
          },
          "recurrenceKind": {
            "type": "string",
            "enum": [
              "none",
              "day",
              "week",
              "month"
            ],
            "description": "Repeat the window daily, weekly or monthly at the same local time. `none` is a one-off window."
          },
          "timezone": {
            "type": "string",
            "default": "UTC",
            "description": "IANA time zone used for repeating windows, for example `Europe/Berlin`."
          },
          "recurring": {
            "type": "boolean",
            "description": "Older form. Prefer `recurrenceKind`."
          },
          "recurrenceRule": {
            "type": "string",
            "description": "Older form: a stored recurrence rule. Prefer `recurrenceKind`."
          }
        }
      },
      "UpdateMaintenanceWindowRequest": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Window name shown on status pages."
          },
          "description": {
            "type": "string"
          },
          "startTime": {
            "type": "string",
            "format": "date-time"
          },
          "endTime": {
            "type": "string",
            "format": "date-time",
            "description": "Must be after `startTime` and at most 90 days later. Alerts for the linked monitors are suppressed during the window."
          },
          "monitorIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Replaces the covered monitors."
          },
          "recurrenceKind": {
            "type": "string",
            "enum": [
              "none",
              "day",
              "week",
              "month"
            ],
            "description": "Repeat the window daily, weekly or monthly at the same local time. `none` is a one-off window."
          },
          "timezone": {
            "type": "string",
            "default": "UTC",
            "description": "IANA time zone used for repeating windows, for example `Europe/Berlin`."
          },
          "recurring": {
            "type": "boolean",
            "description": "Older form. Prefer `recurrenceKind`."
          },
          "recurrenceRule": {
            "type": "string",
            "description": "Older form: a stored recurrence rule. Prefer `recurrenceKind`."
          },
          "skippedOccurrences": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Occurrence start times to skip. Replaces the stored list."
          }
        }
      },
      "UpdateIncidentRequest": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "INVESTIGATING",
              "IDENTIFIED",
              "MONITORING",
              "RESOLVED",
              "POSTMORTEM"
            ],
            "description": "RESOLVED closes the incident."
          },
          "severity": {
            "type": "string",
            "enum": [
              "CRITICAL",
              "HIGH",
              "MEDIUM",
              "LOW",
              "INFO"
            ],
            "description": "Case-insensitive."
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          "resolution": {
            "type": "string",
            "maxLength": 2000
          },
          "rootCause": {
            "type": "string",
            "maxLength": 2000
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time"
          },
          "acknowledged": {
            "type": "boolean",
            "description": "true acknowledges the incident now, as the caller; false clears it. Repeat reminders stop while an open incident is acknowledged; the recovery still notifies."
          },
          "acknowledgedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Older form of `acknowledged`: a time acknowledges at that time, null clears. Must agree with `acknowledged` when both are sent."
          },
          "autoResolve": {
            "type": "boolean",
            "description": "false keeps this incident open after the monitor recovers, until someone resolves it."
          },
          "notify": {
            "type": "boolean",
            "default": true,
            "description": "Applies when `status` changes the incident's status. true (the default) sends the change at once to the incident's alert channels and to the subscribers of its status pages. false records it on the incident timeline without notifying anyone; the status page still shows the new status. PagerDuty, Opsgenie and Prometheus only receive a close or a reopen of an alert that a check opened."
          },
          "actionId": {
            "type": "string",
            "format": "uuid",
            "description": "A UUID you choose for a status change. Sending the request again with the same actionId changes and announces the incident only once: the repeat returns 200 and sends nothing, and may include `replayed: true`. An actionId already used on another incident returns 409."
          }
        }
      },
      "MonitorAlertMuteRequest": {
        "type": "object",
        "required": [
          "durationMinutes"
        ],
        "properties": {
          "durationMinutes": {
            "type": "integer",
            "enum": [
              60,
              480,
              1440,
              10080
            ],
            "description": "How long to mute, in minutes: 60 (1 hour), 480 (8 hours), 1440 (24 hours) or 10080 (7 days). Must be a JSON number; any other value is rejected. The mute ends this many minutes after the request."
          }
        }
      },
      "MonitorAlertMuteResponse": {
        "type": "object",
        "required": [
          "alertsMutedUntil"
        ],
        "properties": {
          "alertsMutedUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the mute ends. Null after an unmute."
          }
        }
      },
      "MonitorServerMatch": {
        "type": "object",
        "required": [
          "serverId",
          "matchType"
        ],
        "properties": {
          "serverId": {
            "type": "string",
            "format": "uuid"
          },
          "matchType": {
            "type": "string",
            "enum": [
              "ip",
              "inferred_ip",
              "hostname"
            ],
            "description": "`ip`: the server address is one the URL resolves to. `inferred_ip`: a managed-host server whose other linked websites share that address. `hostname`: the server hostname equals the URL hostname."
          },
          "matchedIp": {
            "type": "string",
            "description": "The address that matched (absent for `hostname` matches)."
          }
        }
      },
      "MonitorServerResolveResponse": {
        "type": "object",
        "required": [
          "resolvedIps",
          "matchedServers"
        ],
        "properties": {
          "resolvedIps": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Addresses the monitor URL resolves to now, plus origin addresses found through a connected Cloudflare integration. Empty when the monitor has no URL."
          },
          "matchedServers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitorServerMatch"
            }
          }
        }
      },
      "MonitorServerSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "ipAddress": {
            "type": [
              "string",
              "null"
            ]
          },
          "hostname": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "ONLINE",
              "OFFLINE",
              "DEGRADED",
              "MAINTENANCE",
              "UNKNOWN"
            ]
          },
          "cpuUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent."
          },
          "memoryUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent."
          },
          "diskUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent."
          },
          "agentLastSeen": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "monitoringMode": {
            "type": "string",
            "enum": [
              "AGENT",
              "MANAGED_HOST"
            ]
          },
          "hostingProvider": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "HOSTINGER",
              "OTHER",
              null
            ]
          },
          "_count": {
            "type": "object",
            "properties": {
              "monitorLinks": {
                "type": "integer",
                "description": "Monitors confirmed as hosted on this server."
              }
            }
          }
        }
      },
      "MonitorServerListEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Link ID, used as `msId`."
          },
          "serverId": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ]
          },
          "resolvedIp": {
            "type": [
              "string",
              "null"
            ],
            "description": "The address that produced an automatic match."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "server": {
            "$ref": "#/components/schemas/MonitorServerSummary"
          }
        }
      },
      "MonitorServerListResponse": {
        "type": "object",
        "properties": {
          "linked": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitorServerListEntry"
            },
            "description": "Confirmed links, newest first."
          },
          "suggestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitorServerListEntry"
            },
            "description": "Automatic matches waiting to be confirmed or dismissed, newest first."
          },
          "resolvedIps": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Addresses from the last lookup."
          },
          "resolvedIpAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the last lookup ran."
          }
        }
      },
      "MonitorServerLink": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "monitorId": {
            "type": "string",
            "format": "uuid"
          },
          "serverId": {
            "type": "string",
            "format": "uuid"
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "suggested",
              "dismissed"
            ]
          },
          "resolvedIp": {
            "type": [
              "string",
              "null"
            ]
          },
          "driftIp": {
            "type": [
              "string",
              "null"
            ]
          },
          "driftDetectedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "MonitorBulkSkip": {
        "type": "object",
        "required": [
          "id",
          "reason"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "description": "Plain-language reason, usually the `error` text the single-monitor route returned."
          }
        }
      },
      "MonitorBulkResult": {
        "type": "object",
        "required": [
          "updated",
          "skipped",
          "unchanged"
        ],
        "properties": {
          "updated": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Monitors the change was applied to."
          },
          "skipped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MonitorBulkSkip"
            },
            "description": "Monitors left alone, each with a reason."
          },
          "unchanged": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Monitors already in the requested state."
          }
        }
      },
      "MonitorBulkRateLimitError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "Rate limit exceeded"
            ]
          },
          "limit": {
            "type": "integer"
          },
          "reset": {
            "type": "string",
            "format": "date-time"
          },
          "remaining": {
            "type": "integer"
          }
        }
      },
      "MonitorBulkSettings": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "description": "Every field is optional; only the fields sent are changed. At least one is required, and unknown fields are rejected.",
        "properties": {
          "checkInterval": {
            "type": "integer",
            "minimum": 30,
            "maximum": 86400,
            "description": "Seconds between checks. Your plan minimum still applies per monitor."
          },
          "timeout": {
            "type": "integer",
            "minimum": 1000,
            "maximum": 120000,
            "description": "Request timeout in milliseconds."
          },
          "alertThreshold": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Confirmed failed checks in a row before the down alert."
          },
          "locations": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 40
            },
            "description": "Check regions, for example `EU` or `US`. Regions your plan does not include, or that are unavailable, cause that monitor to be skipped."
          },
          "followRedirects": {
            "type": "boolean"
          },
          "sslCheck": {
            "type": "boolean"
          },
          "visualEnabled": {
            "type": "boolean",
            "description": "Turn visual monitoring on or off. Plan and monitor-type rules apply per monitor."
          },
          "domainExpiryEnabled": {
            "type": "boolean"
          },
          "reminders": {
            "type": "string",
            "enum": [
              "standard",
              "none"
            ],
            "description": "`standard` sets certificate reminders to 13, 3 and 1 days before expiry and domain reminders to 50, 13, 3 and 1 days; `none` clears both lists."
          }
        }
      },
      "MonitorBulkLinkServerResponse": {
        "type": "object",
        "properties": {
          "linked": {
            "type": "integer",
            "description": "Links created or upgraded to a confirmed manual link."
          },
          "alreadyLinked": {
            "type": "integer",
            "description": "Monitors that already had a confirmed link to the server. Absent when no monitor was eligible."
          },
          "skipped": {
            "type": "integer",
            "enum": [
              0
            ],
            "description": "Only present (always 0) when no monitor was eligible."
          },
          "total": {
            "type": "integer",
            "description": "Eligible monitors (IDs that belong to your organization)."
          },
          "serverName": {
            "type": "string",
            "description": "Absent when no monitor was eligible."
          },
          "message": {
            "type": "string"
          }
        }
      },
      "BulkUpdateAlertsRequest": {
        "type": "object",
        "required": [
          "monitorIds"
        ],
        "description": "Send `updates`, `channelAction`, or both. `notificationChannelIds` is required with `channelAction`; it may be empty only for `replace`, which then removes every channel from the monitors.",
        "properties": {
          "monitorIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "minItems": 1,
            "maxItems": 2000,
            "description": "Every ID must be a monitor of your organization and IDs must not repeat, otherwise the request is refused with 403 and nothing changes."
          },
          "updates": {
            "type": "object",
            "properties": {
              "alertThreshold": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10,
                "description": "Confirmed failed checks in a row before the down alert."
              },
              "slowAlertThreshold": {
                "type": "integer",
                "minimum": 1,
                "maximum": 10,
                "description": "Slow responses in a row before the slow alert."
              },
              "alertDelay": {
                "type": "integer",
                "minimum": 0,
                "maximum": 900,
                "description": "Seconds to wait before alerting."
              },
              "notificationRepeatInterval": {
                "type": "integer",
                "minimum": 0,
                "maximum": 1440,
                "description": "Minutes between reminders while a problem lasts; 0 sends none."
              },
              "visualCheckInterval": {
                "type": "integer",
                "minimum": 900,
                "maximum": 86400,
                "description": "Seconds between visual checks. Applied only to monitors with visual monitoring on."
              }
            }
          },
          "channelAction": {
            "type": "string",
            "enum": [
              "replace",
              "add",
              "remove"
            ],
            "description": "`replace` sets the monitors' channels to exactly `notificationChannelIds`; `add` adds them; `remove` removes them."
          },
          "notificationChannelIds": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Notification channels of your organization."
          }
        }
      },
      "IncidentContext": {
        "type": "object",
        "description": "Everything the incident detail view shows, in one read.",
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "incident": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "title": {
                "type": "string"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "state": {
                "type": "string",
                "enum": [
                  "ongoing",
                  "acknowledged",
                  "resolved"
                ]
              },
              "rawStatus": {
                "type": "string",
                "description": "Stored status, for example INVESTIGATING or RESOLVED."
              },
              "startedAt": {
                "type": "string",
                "format": "date-time"
              },
              "detectedAt": {
                "type": "string",
                "format": "date-time"
              },
              "acknowledgedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "acknowledgedBy": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              },
              "resolvedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "durationMs": {
                "type": "integer"
              },
              "autoResolve": {
                "type": "boolean"
              },
              "rootCause": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "resolution": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "monitorId": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "serverId": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "visualTargetId": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              },
              "metadata": {
                "description": "Stored incident metadata (any JSON)."
              },
              "severity": {
                "type": "string",
                "description": "critical, high, medium, low or info."
              },
              "incidentKind": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "reported": {
                "type": "boolean",
                "description": "A person reported the incident."
              },
              "reportedBy": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "owner": {
            "type": "string",
            "enum": [
              "uptime",
              "ssl",
              "performance",
              "domain",
              "content",
              "visual",
              "security",
              "server",
              "other"
            ]
          },
          "checkType": {
            "type": "string",
            "enum": [
              "other_address",
              "uptime",
              "ssl",
              "domain",
              "performance",
              "content",
              "visual",
              "security",
              "server",
              "manual"
            ]
          },
          "cause": {
            "type": "string",
            "enum": [
              "other_address",
              "http_error",
              "checker_blocked",
              "checker_rate_limited",
              "timeout",
              "dns",
              "refused",
              "down",
              "certificate_expired",
              "certificate_self_signed",
              "certificate_mismatch",
              "certificate_problem",
              "ssl_expiring",
              "ssl_expired",
              "slow",
              "performance",
              "domain_expired",
              "visual_change",
              "content_failed",
              "security",
              "server",
              "manual"
            ]
          },
          "headline": {
            "type": "string"
          },
          "shortCause": {
            "type": [
              "string",
              "null"
            ]
          },
          "summary": {
            "type": "object",
            "properties": {
              "what": {
                "type": "string"
              },
              "where": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "next": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "steps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fixActions": {
            "type": "array",
            "description": "Suggested fixes. Empty unless your role is Owner, Admin or Developer.",
            "items": {
              "type": "object",
              "required": [
                "kind"
              ],
              "properties": {
                "kind": {
                  "type": "string",
                  "enum": [
                    "ssl_check",
                    "settings_link",
                    "bot_page",
                    "server_link",
                    "mute"
                  ]
                },
                "enabled": {
                  "type": "boolean",
                  "description": "`ssl_check` only."
                },
                "section": {
                  "type": "string",
                  "description": "`settings_link` only: monitor settings section id."
                },
                "serverId": {
                  "type": "string",
                  "description": "`server_link` only."
                },
                "label": {
                  "type": "string"
                }
              }
            }
          },
          "whatWeChecked": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                },
                "at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Optional time to show after `value`."
                }
              }
            }
          },
          "settingsSection": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "general",
              "uptime",
              "ssl",
              "domain",
              "visual",
              "content",
              "performance",
              "dns",
              "alerts",
              "reports",
              "server",
              "danger",
              null
            ]
          },
          "monitor": {
            "type": [
              "object",
              "null"
            ],
            "description": "Null for server incidents and when the monitor was deleted.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "url": {
                "type": "string"
              },
              "enabled": {
                "type": "boolean"
              },
              "checkInterval": {
                "type": "integer"
              },
              "timeout": {
                "type": "integer"
              },
              "alertThreshold": {
                "type": "integer"
              },
              "maxResponseTime": {
                "type": "integer"
              },
              "locations": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "sslCheck": {
                "type": "boolean"
              },
              "sslAlertDays": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "domainExpiryEnabled": {
                "type": "boolean"
              },
              "domainAlertDays": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "notificationRepeatInterval": {
                "type": "integer",
                "description": "Minutes between reminders; 0 sends none."
              },
              "alertsMutedUntil": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time",
                "description": "End of an active mute; null when alerts are live."
              },
              "alertsMuteExempt": {
                "type": "boolean",
                "description": "True when a mute never holds back this incident's alerts (possible malware)."
              },
              "linkedChannels": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "enabled": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "server": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "cpuUsage": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "memoryUsage": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "diskUsage": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "cpuCores": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "loadAverage": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "type": "number"
                }
              },
              "loadWarnRatio": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "loadCritRatio": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "agentLastSeen": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "regions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "region": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "failing": {
                  "type": "boolean"
                },
                "latest": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "ok": {
                      "type": "boolean"
                    },
                    "regionalOnly": {
                      "type": "boolean"
                    },
                    "result": {
                      "type": "string"
                    },
                    "statusCode": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "checkLog": {
            "type": "object",
            "description": "Checks from 15 minutes before the start to the resolution (or now). When the window holds more than 50 checks, the newest 50 and oldest 10 are returned and `omitted` counts the rest.",
            "properties": {
              "windowStart": {
                "type": "string",
                "format": "date-time"
              },
              "windowEnd": {
                "type": "string",
                "format": "date-time"
              },
              "rows": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "region": {
                      "type": "string"
                    },
                    "regionLabel": {
                      "type": "string"
                    },
                    "ok": {
                      "type": "boolean"
                    },
                    "regionalOnly": {
                      "type": "boolean"
                    },
                    "statusCode": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "result": {
                      "type": "string"
                    },
                    "error": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "errorCode": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "responseTimeMs": {
                      "type": [
                        "number",
                        "null"
                      ]
                    }
                  }
                }
              },
              "omitted": {
                "type": "integer"
              }
            }
          },
          "certificate": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "validFrom": {
                "type": "string",
                "format": "date-time"
              },
              "validTo": {
                "type": "string",
                "format": "date-time"
              },
              "daysRemaining": {
                "type": "integer"
              },
              "issuer": {
                "type": "string"
              },
              "subject": {
                "type": "string"
              },
              "algorithm": {
                "type": "string"
              },
              "keySize": {
                "type": "integer"
              },
              "altNames": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "visualDiff": {
            "type": [
              "object",
              "null"
            ],
            "description": "Before and after screenshots recorded with a visual incident.",
            "properties": {
              "a": {
                "type": "string",
                "description": "Baseline image path."
              },
              "b": {
                "type": "string",
                "description": "Capture image path."
              },
              "diff": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "percent": {
                "type": "number"
              },
              "threshold": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "screenshotId": {
                "type": "string"
              },
              "visualTargetId": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "viewport": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "DESKTOP",
                  "MOBILE",
                  null
                ]
              },
              "targetLabel": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "exact": {
                "type": "boolean",
                "enum": [
                  true
                ]
              }
            }
          },
          "checksInRow": {
            "type": "object",
            "properties": {
              "count": {
                "type": "integer"
              },
              "atLeast": {
                "type": "boolean",
                "description": "True when the stored log is cut short, so the real count may be higher."
              }
            }
          },
          "uptimeToday": {
            "type": [
              "object",
              "null"
            ],
            "description": "The monitor's day so far in the `tz` time zone (UTC when not given or not valid).",
            "properties": {
              "percent": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "downSeconds": {
                "type": "integer"
              },
              "since": {
                "type": "string",
                "format": "date-time"
              },
              "slots": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "ok",
                    "bad",
                    "none"
                  ]
                }
              }
            }
          },
          "sentEvents": {
            "type": "array",
            "description": "Alerts that went out, one per event.",
            "items": {
              "type": "object",
              "properties": {
                "event": {
                  "type": "string",
                  "enum": [
                    "opened",
                    "reminder",
                    "recovered"
                  ]
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "sent": {
                  "type": "integer"
                },
                "failed": {
                  "type": "integer"
                },
                "pending": {
                  "type": "integer"
                },
                "total": {
                  "type": "integer"
                }
              }
            }
          },
          "earlierOnMonitor": {
            "type": "array",
            "description": "Up to three earlier resolved incidents of the same monitor.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "title": {
                  "type": "string"
                },
                "source": {
                  "type": "string"
                },
                "startedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "durationMs": {
                  "type": "integer"
                },
                "checkType": {
                  "type": "string"
                }
              }
            }
          },
          "publicPreview": {
            "type": [
              "object",
              "null"
            ],
            "description": "What the first public status page showing this monitor says right now.",
            "properties": {
              "statusPage": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string"
                  },
                  "host": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "services": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "degraded",
                        "problem",
                        "maintenance"
                      ]
                    }
                  }
                }
              },
              "incident": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "message": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          },
          "statusPages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "deliveries": {
            "type": [
              "array",
              "null"
            ],
            "description": "Who was told, per channel, oldest first. Empty for incidents from before delivery records existed; null when the record could not be read.",
            "items": {
              "type": "object",
              "properties": {
                "event": {
                  "type": "string",
                  "description": "`update` is what a person's manual close, update or reopen sent.",
                  "enum": [
                    "opened",
                    "reminder",
                    "recovered",
                    "update",
                    "other"
                  ]
                },
                "channelId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "channelName": {
                  "type": "string"
                },
                "channelType": {
                  "type": "string",
                  "description": "Channel type such as EMAIL or SLACK, or ALL for an outcome that applied to every channel."
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "sent",
                    "not_sent",
                    "pending"
                  ]
                },
                "reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "description": "Plain-language reason when not sent or still pending."
                },
                "at": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "updates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "status": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                },
                "authorName": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "system": {
                  "type": "boolean"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          },
          "muteEvents": {
            "type": "array",
            "description": "Alert mutes and unmutes of the monitor while the incident was open, oldest first.",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "muted",
                    "unmuted"
                  ]
                },
                "byName": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "until": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time",
                  "description": "End of the mute, for `muted`."
                }
              }
            }
          },
          "related": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "title": {
                  "type": "string"
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "ongoing",
                    "acknowledged",
                    "resolved"
                  ]
                },
                "startedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "resolvedAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            }
          },
          "cluster": {
            "type": [
              "object",
              "null"
            ],
            "description": "Present only for incidents tied to a server: the monitors on that server it affects and its child incidents. Null otherwise.",
            "additionalProperties": true,
            "properties": {
              "affectedMonitors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "clusterRollup": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": true
              },
              "separateOpenIssues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": true
                }
              },
              "childIncidents": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "title": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "severity": {
                      "type": "string"
                    },
                    "monitorId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "monitor": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              },
              "parentIncident": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "title": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "viewer": {
            "type": "object",
            "properties": {
              "canEdit": {
                "type": "boolean",
                "description": "Owner, Admin or Developer."
              },
              "canPostStatusUpdate": {
                "type": "boolean",
                "description": "Owner or Admin."
              }
            }
          }
        }
      },
      "AlertDeliveryLog": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "description": "Alert events, newest first, 50 per page.",
            "items": {
              "$ref": "#/components/schemas/AlertDeliveryLogEvent"
            }
          },
          "summary": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Alert events in the range (after the `status` filter)."
              },
              "failed": {
                "type": "integer",
                "description": "Channel deliveries not sent, for any reason (including mutes and pauses)."
              },
              "perDay": {
                "type": "array",
                "description": "Always seven UTC days ending today, counted from the rows the range and `status` filter selected.",
                "items": {
                  "type": "object",
                  "properties": {
                    "day": {
                      "type": "string",
                      "format": "date"
                    },
                    "sent": {
                      "type": "integer",
                      "description": "Alert events with at least one channel delivery sent that day."
                    },
                    "failed": {
                      "type": "integer",
                      "description": "Channel deliveries the channel did not accept (reason `failed`) that day."
                    }
                  }
                }
              }
            }
          },
          "page": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer",
            "description": "At least 1."
          }
        }
      },
      "AlertDeliveryLogEvent": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "Time of the newest delivery record for the event."
          },
          "monitorName": {
            "type": "string"
          },
          "incidentId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "event": {
            "type": "string",
            "description": "`update` is what a person's manual close, update or reopen sent. Records made before this value existed say `other` with alertType INCIDENT_UPDATE.",
            "enum": [
              "opened",
              "reminder",
              "recovered",
              "update",
              "other"
            ]
          },
          "alertType": {
            "type": "string",
            "description": "For example DOWN, RECOVERY, SSL_EXPIRING or VISUAL_CHANGE."
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "channelId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid",
                  "description": "Null for an outcome that applied to every channel."
                },
                "name": {
                  "type": "string",
                  "description": "Channel name, or the channel type when the channel no longer exists or the outcome applied to every channel (`ALL`)."
                },
                "type": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "sent",
                    "not_sent"
                  ]
                },
                "reason": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "failed",
                    "unverified_email",
                    "no_recipients",
                    "unsupported",
                    "rate_limited",
                    "muted",
                    "org_paused",
                    "no_channels",
                    null
                  ],
                  "description": "Set for `not_sent` only."
                }
              }
            }
          }
        }
      },
      "StatusPageGroup": {
        "type": "object",
        "description": "A named group of components on a status page",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "statusPageId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "order": {
            "type": "integer",
            "description": "Display position, starting at 1"
          },
          "tagRule": {
            "type": [
              "string",
              "null"
            ],
            "description": "Monitor tag that drives automatic membership, or null for a manual group"
          },
          "autoSync": {
            "type": "boolean",
            "description": "True when the group's membership follows its tag rule"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "StatusPageGroupSyncResult": {
        "type": "object",
        "description": "What the tag sync changed. All zero for a group without a tag rule.",
        "properties": {
          "linked": {
            "type": "integer",
            "description": "Monitors with the tag that were added to the status page in this group"
          },
          "assigned": {
            "type": "integer",
            "description": "Monitors already on the page, ungrouped and carrying the tag, that were moved into this group"
          },
          "released": {
            "type": "integer",
            "description": "Monitors in this group without the tag that were moved out of the group (they stay on the page)"
          }
        }
      },
      "StatusPageMonitorListItem": {
        "type": "object",
        "description": "A monitor linked to a status page, as returned by the list endpoint",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Monitor ID"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/MonitorStatus"
          },
          "uptimePercent": {
            "type": "number"
          },
          "type": {
            "$ref": "#/components/schemas/StoredMonitorType"
          },
          "lastCheckedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "order": {
            "type": "integer",
            "description": "Display position on this status page"
          },
          "groupId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Group on this status page, or null when ungrouped"
          }
        }
      },
      "StatusPageMonitorLink": {
        "type": "object",
        "description": "The link between a monitor and a status page, with its display options",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Link ID"
          },
          "statusPageId": {
            "type": "string",
            "format": "uuid"
          },
          "monitorId": {
            "type": "string",
            "format": "uuid"
          },
          "groupId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ]
          },
          "order": {
            "type": "integer"
          },
          "showGraph": {
            "type": "boolean"
          },
          "showResponseTime": {
            "type": "boolean"
          },
          "showSSL": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "StatusPageServerListItem": {
        "type": "object",
        "description": "A server linked to a status page, as returned by the list endpoint",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Server ID"
          },
          "name": {
            "type": "string"
          },
          "hostname": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "ONLINE",
              "OFFLINE",
              "DEGRADED",
              "MAINTENANCE",
              "UNKNOWN"
            ]
          },
          "cpuUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent"
          },
          "memoryUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent"
          },
          "diskUsage": {
            "type": [
              "number",
              "null"
            ],
            "description": "Percent"
          },
          "uptime": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Seconds since the server booted, as last reported by the agent"
          },
          "agentLastSeen": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ],
            "description": "Name shown on this status page"
          },
          "showMetrics": {
            "type": "boolean"
          },
          "order": {
            "type": "integer",
            "description": "Display position on this status page"
          }
        }
      },
      "StatusPageServerLink": {
        "type": "object",
        "description": "The link between a server and a status page, with its display options",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Link ID"
          },
          "statusPageId": {
            "type": "string",
            "format": "uuid"
          },
          "serverId": {
            "type": "string",
            "format": "uuid"
          },
          "displayName": {
            "type": [
              "string",
              "null"
            ]
          },
          "order": {
            "type": "integer"
          },
          "showMetrics": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "JsonValue": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          },
          {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JsonValue"
            }
          },
          {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            }
          }
        ]
      }
    }
  },
  "security": [
    {
      "SessionAuth": []
    },
    {
      "ApiKeyAuth": []
    }
  ]
}
