openapi: 3.1.0 info: title: Supercheck API version: 1.0.0 description: API for test automation, monitoring, and CI/CD integration. Supercheck provides Playwright browser testing, k6 performance testing, uptime monitoring, and alerting — all managed via API or CLI. contact: name: Supercheck url: https://supercheck.io license: name: AGPL-3.0-only url: https://github.com/supercheck-io/supercheck/blob/main/LICENSE servers: - url: https://demo.supercheck.dev description: Demo - url: https://app.supercheck.io description: Production (Cloud) security: - bearerAuth: [] tags: - name: Authentication description: CLI token management and verification - name: Jobs description: Job scheduling and execution - name: Trigger Keys description: API trigger key management for jobs - name: Runs description: Job run management and monitoring - name: Tests description: Test script management - name: Monitors description: Uptime and performance monitoring - name: Variables description: Project environment variables - name: Tags description: Resource tagging - name: Notifications description: Notification provider management - name: Alerts description: Alert history - name: Audit description: Audit log access - name: AI SRE description: Project-scoped incident response, investigation, Copilot, and service topology - name: System description: Health checks and metadata - name: Status Pages description: Manage status pages for uptime dashboards - name: Organizations description: Organization membership, settings, invitations, and usage stats. Session cookies or CLI bearer tokens are accepted. Organizations are created automatically at signup; POST is disabled. - name: Requirements description: Requirements, their tags and linked tests, and CSV export paths: /api/sre/incidents: get: operationId: listSreIncidents summary: List AI SRE incidents tags: - AI SRE parameters: - name: incidentNumber in: query description: Resolve an incident number within the authenticated organization and project. schema: type: integer minimum: 1 maximum: 2147483647 - name: status in: query schema: type: string enum: - open - triggered - investigating - identified - recommendations_ready - user_applying_fix - verifying - resolved description: Filter by incident status. `open` returns every incident that is not `resolved`. - name: severity in: query schema: type: string enum: - sev1 - sev2 - sev3 - sev4 responses: "200": description: Tenant-scoped incident list "400": description: Invalid filters "401": description: Authentication required "403": description: Insufficient permission /api/sre/incidents/{id}: get: operationId: getSreIncident summary: Get an AI SRE incident tags: - AI SRE parameters: - name: id in: path required: true schema: type: string format: uuid responses: "200": description: Incident details "404": description: Incident not found in the active project /api/sre/incidents/{id}/timeline: get: operationId: getSreIncidentTimeline summary: Get an incident timeline tags: - AI SRE parameters: - name: id in: path required: true schema: type: string format: uuid responses: "200": description: Chronological incident timeline "404": description: Incident not found in the active project /api/sre/incidents/{id}/resolve: post: operationId: resolveSreIncident summary: Resolve an incident with an audit comment tags: - AI SRE parameters: - name: id in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: type: object required: - comment properties: comment: type: string minLength: 1 maxLength: 2000 responses: "200": description: Incident resolved; timeline and audit events recorded "400": description: Invalid ID or comment "403": description: Insufficient permission "404": description: Incident not found in the active project /api/sre/triage: post: operationId: triageSreIncident summary: Run AI incident triage tags: - AI SRE requestBody: required: true content: application/json: schema: type: object required: - incidentId properties: incidentId: type: string format: uuid responses: "200": description: Triage result "402": description: An active organization subscription and valid billing customer are required on Supercheck Cloud. "429": description: Rate limited "503": description: SRE is disabled, or subscription verification or the service is temporarily unavailable. /api/sre/investigate: post: operationId: startSreInvestigation summary: Start an asynchronous deep investigation description: Returns a durable investigationRunId before background execution finishes. Poll the incident details to review the run status and saved result. Live connectors require explicit opt-in and connector investigation permission. tags: - AI SRE requestBody: required: true content: application/json: schema: type: object required: - incidentId properties: incidentId: type: string format: uuid useLiveConnectors: type: boolean default: false responses: "202": description: Investigation accepted content: application/json: schema: type: object required: - success - accepted - investigationRunId properties: success: type: boolean const: true accepted: type: boolean const: true investigationRunId: type: string format: uuid "400": description: Invalid investigation request content: application/json: schema: type: object properties: error: type: string code: type: string "401": description: Authentication required content: application/json: schema: type: object properties: error: type: string code: type: string "402": description: Execution access denied content: application/json: schema: type: object properties: error: type: string code: type: string "403": description: Insufficient permissions or invalid request origin content: application/json: schema: type: object properties: error: type: string code: type: string "404": description: Incident not found content: application/json: schema: type: object properties: error: type: string code: type: string "409": description: An investigation is already running for this incident "429": description: Rate limited "503": description: Feature disabled or temporarily unavailable /api/sre/runs/{id}: get: operationId: getSreInvestigationRun summary: Get an AI SRE investigation run description: Returns the status of a run started by the investigate or triage endpoints. Scoped to the active project. tags: - AI SRE parameters: - name: id in: path required: true schema: type: string format: uuid responses: "200": description: Investigation run content: application/json: schema: type: object required: - run properties: run: type: object properties: id: type: string format: uuid incidentId: type: string format: uuid nullable: true agentType: type: string status: type: string startedAt: type: string format: date-time nullable: true completedAt: type: string format: date-time nullable: true durationMs: type: integer nullable: true "400": description: Invalid investigation run ID "404": description: Investigation run not found in the active project /api/sre/chat: post: operationId: streamSreChat summary: Stream a read-only Copilot conversation tags: - AI SRE requestBody: required: true content: application/json: schema: type: object required: - message properties: message: type: string minLength: 1 maxLength: 4000 incidentId: type: - string - "null" format: uuid conversationId: type: - string - "null" format: uuid useLiveConnectorTools: type: boolean default: true description: Read-only live connectors are enabled by default when authorized. Set false to use conversation text and stored incident evidence only. General chat uses selected project services; incident chat stays scoped to its linked service. responses: "200": description: Server-sent event stream "402": description: An active organization subscription and valid billing customer are required on Supercheck Cloud. "429": description: Rate limited "503": description: SRE is disabled, or subscription verification or the service is temporarily unavailable. /api/sre/evidence-brief/stream: post: operationId: streamSreEvidenceBrief summary: Generate and stream an incident evidence brief tags: - AI SRE requestBody: required: true content: application/json: schema: type: object required: - incidentId properties: incidentId: type: string format: uuid responses: "200": description: Server-sent event stream "402": description: An active organization subscription and valid billing customer are required on Supercheck Cloud. "429": description: Rate limited "503": description: SRE is disabled, or subscription verification or the service is temporarily unavailable. /api/sre/services: get: operationId: listSreServices summary: List AI SRE services tags: - AI SRE responses: "200": description: Tenant-scoped service catalog "403": description: Insufficient permission /api/sre/services/{id}: get: operationId: getSreService summary: Get service details, health, and dependencies tags: - AI SRE parameters: - name: id in: path required: true schema: type: string format: uuid responses: "200": description: Service, latest health snapshot, and dependency edges "404": description: Service not found in the active project /api/health: get: operationId: getHealth summary: Health check description: Returns the health status of the API and its dependencies (database, Redis, storage). tags: - System security: [] responses: "200": description: Health status content: application/json: schema: type: object properties: status: type: string enum: - ok - degraded - unhealthy timestamp: type: string format: date-time latencyMs: type: integer checks: type: object properties: database: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string redis: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string s3: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string build: type: object properties: revision: type: string required: - revision required: - status - timestamp - latencyMs - checks - build "503": description: Service unhealthy content: application/json: schema: type: object properties: status: type: string enum: - ok - degraded - unhealthy timestamp: type: string format: date-time latencyMs: type: integer checks: type: object properties: database: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string redis: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string s3: type: object properties: status: type: string enum: - ok - error latencyMs: type: integer error: type: string required: - status - timestamp - latencyMs - checks /api/locations: get: operationId: listLocations summary: List execution locations description: Returns enabled execution locations visible in the current hosting mode. Authentication is required. tags: - System responses: "200": description: Available locations content: application/json: schema: type: object properties: success: type: boolean example: true data: type: array items: $ref: "#/components/schemas/Location" /api/cli-tokens: get: operationId: listCliTokens summary: List CLI tokens description: List all CLI tokens for the current project. Also used by `supercheck whoami` to verify the current token. tags: - Authentication responses: "200": description: List of CLI tokens content: application/json: schema: type: object properties: success: type: boolean tokens: type: array items: $ref: "#/components/schemas/CliToken" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createCliToken summary: Create a CLI token description: Create a new CLI token for API access. The plain token value is returned only once in the response — store it securely. tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Human-readable token name example: CI/CD Pipeline expiresIn: type: integer description: Optional expiration duration in seconds (min 3600 = 1 hour, max 31536000 = 1 year) example: 7776000 minimum: 3600 maximum: 31536000 required: - name responses: "201": description: Token created. The `key` field contains the plain token — store it securely, it cannot be retrieved again. content: application/json: schema: type: object properties: success: type: boolean token: type: object properties: id: type: string format: uuid name: type: string key: type: string description: Plain token value (shown only once) example: sck_live_a1b2c3d4e5f6789012345678901234ab start: type: string description: Display prefix for identification enabled: type: boolean expiresAt: type: string format: date-time nullable: true createdAt: type: string format: date-time "401": $ref: "#/components/responses/Unauthorized" "409": description: Duplicate token name within this project /api/cli-tokens/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: CLI token ID patch: operationId: updateCliToken summary: Update a CLI token description: Enable, disable, or rename a CLI token. tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean name: type: string responses: "200": description: Token updated content: application/json: schema: type: object properties: success: type: boolean token: type: object properties: id: type: string format: uuid name: type: string enabled: type: boolean "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteCliToken summary: Revoke a CLI token description: Permanently delete a CLI token. This action cannot be undone. tags: - Authentication responses: "200": description: Token revoked content: application/json: schema: type: object properties: success: type: boolean message: type: string "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/jobs: get: operationId: listJobs summary: List jobs description: List all jobs in the current project with pagination. tags: - Jobs parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/JobLimit" - name: includeScript in: query schema: type: boolean description: Include the decoded script in each job's tests. Defaults to false. Pages are limited to 25 jobs when scripts are included. responses: "200": description: Paginated list of jobs content: application/json: schema: allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: $ref: "#/components/schemas/Job" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createJob summary: Create a job description: Create a new job with optional scheduling and test configuration. tags: - Jobs requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/JobCreateRequest" responses: "200": description: Job created content: application/json: schema: $ref: "#/components/schemas/JobCreateResponse" "400": description: Invalid job payload "401": $ref: "#/components/responses/Unauthorized" "402": description: Access denied by deployment policy "403": $ref: "#/components/responses/Forbidden" /api/jobs/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Job ID get: operationId: getJob summary: Get job details description: Retrieve full details for a job including its tests and last run information. tags: - Jobs responses: "200": description: Job details content: application/json: schema: $ref: "#/components/schemas/Job" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" patch: operationId: updateJob summary: Update a job description: Update job configuration. Only provided fields are changed. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Jobs requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/JobUpdateRequest" responses: "200": description: Job updated content: application/json: schema: $ref: "#/components/schemas/JobUpdateResponse" "400": description: Invalid job update payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteJob summary: Delete a job description: Permanently delete a job and all its associated runs. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Jobs responses: "200": description: Job deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string required: - success - message "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" put: operationId: replaceJobConfiguration summary: Update a job configuration description: Update job configuration. Only provided fields are changed. PUT is retained for CLI deploy and backward compatibility; interactive partial updates should prefer PATCH. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Jobs requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/JobUpdateRequest" responses: "200": description: Job updated content: application/json: schema: $ref: "#/components/schemas/JobUpdateResponse" "400": description: Invalid job update payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/jobs/{id}/trigger: parameters: - name: id in: path required: true schema: type: string format: uuid description: Job ID post: operationId: triggerJob summary: Trigger job execution description: "Trigger a job run using a job-scoped trigger key in the `Authorization: Bearer ` header. For k6 jobs, an optional `location` query parameter can target an enabled location code or `global` for unrestricted any-worker routing. Note: this endpoint only accepts a job trigger key (`sck_trigger_*` / legacy `job_*`) in the `Authorization` header. CLI tokens (`sck_live_*`) are rejected with 401." tags: - Jobs parameters: - name: location in: query required: false schema: type: string description: Optional execution location for k6 jobs. Use an enabled location code (for example `us-east`) or `global` for unrestricted any-worker routing. `global` is rejected when project location restrictions are enabled. responses: "200": description: Job triggered content: application/json: schema: $ref: "#/components/schemas/JobTriggerResponse" "400": description: Invalid job ID, invalid location, or the job cannot be triggered "401": $ref: "#/components/responses/Unauthorized" "402": description: Access denied by deployment policy "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": description: Rate limited — too many trigger requests content: application/json: schema: type: object properties: error: type: string limit: type: integer remaining: type: integer resetAt: type: string format: date-time get: operationId: getJobTriggerInfo summary: Get job trigger information description: Retrieve the authenticated trigger URL and usage instructions for a job. tags: - Jobs responses: "200": description: Trigger information content: application/json: schema: $ref: "#/components/schemas/JobTriggerInfoResponse" "400": description: Invalid job ID format "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/jobs/run: post: operationId: runJob summary: Run a job immediately description: Execute a job immediately by providing its ID. The job's configured tests will be run. For k6 jobs, an optional `location` can target an enabled location code or `global` for unrestricted any-worker routing. tags: - Jobs requestBody: required: true content: application/json: schema: type: object properties: jobId: type: string format: uuid description: ID of the job to run tests: type: array items: type: object properties: id: type: string format: uuid name: type: string title: type: string type: type: string enum: - browser - api - performance - database - custom required: - id minItems: 1 description: Tests to execute for this run. The server validates ownership and uses the stored scripts as the source of truth. trigger: type: string enum: - manual - remote description: Requested trigger source. CLI-authenticated calls are normalized to `remote` by the server. location: type: string description: Optional execution location for k6 jobs. Use an enabled location code (for example `us-east`) or `global` for unrestricted any-worker routing. `global` is rejected when project location restrictions are enabled. required: - jobId - tests - trigger responses: "200": description: Job started content: application/json: schema: type: object properties: runId: type: string format: uuid jobId: type: string format: uuid message: type: string "400": description: Invalid job execution payload "401": $ref: "#/components/responses/Unauthorized" "402": description: Access denied by deployment policy "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/jobs/{id}/api-keys: parameters: - name: id in: path required: true schema: type: string format: uuid description: Job ID get: operationId: listJobApiKeys summary: List trigger keys description: List all API trigger keys for a specific job. tags: - Trigger Keys responses: "200": description: List of trigger keys content: application/json: schema: type: object properties: success: type: boolean apiKeys: type: array items: $ref: "#/components/schemas/TriggerKey" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" post: operationId: createJobApiKey summary: Create a trigger key description: Create a new API trigger key for a job. The plain key is returned only once — store it securely. tags: - Trigger Keys requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: Human-readable name for the trigger key example: GitHub Actions expiresIn: type: integer description: Optional expiration duration in seconds example: 7776000 required: - name responses: "201": description: Trigger key created. Store the `key` value securely — it cannot be retrieved again. content: application/json: schema: type: object properties: success: type: boolean apiKey: type: object properties: id: type: string format: uuid name: type: string key: type: string description: Plain key value (shown only once) example: sck_trigger_f1e2d3c4b5a6789012345678901234cd start: type: string enabled: type: boolean expiresAt: type: string format: date-time nullable: true createdAt: type: string format: date-time "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/jobs/{id}/api-keys/{keyId}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Job ID - name: keyId in: path required: true schema: type: string format: uuid description: Trigger key ID patch: operationId: updateJobApiKey summary: Update a trigger key description: Enable, disable, or rename a trigger key. tags: - Trigger Keys requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean name: type: string responses: "200": description: Trigger key updated content: application/json: schema: type: object properties: success: type: boolean apiKey: $ref: "#/components/schemas/TriggerKey" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteJobApiKey summary: Delete a trigger key description: Permanently delete a trigger key. This action cannot be undone. tags: - Trigger Keys responses: "200": description: Trigger key deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/runs: get: operationId: listRuns summary: List runs description: List job runs with optional filters for job ID and status. tags: - Runs parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/RunLimit" - name: jobId in: query schema: type: string format: uuid description: Filter by job ID. An empty value means no filter; a malformed UUID returns 400. - name: status in: query schema: type: string enum: - queued - running - passed - failed - error - blocked description: Filter by status responses: "200": description: Paginated list of runs content: application/json: schema: allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: $ref: "#/components/schemas/Run" "400": description: The jobId filter is not a canonical UUID. "401": $ref: "#/components/responses/Unauthorized" /api/runs/{runId}: parameters: - name: runId in: path required: true schema: type: string format: uuid description: Run ID get: operationId: getRun summary: Get run details description: Retrieve full details for a specific run including logs, report URL, and execution metadata. tags: - Runs responses: "200": description: Run details content: application/json: schema: $ref: "#/components/schemas/Run" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteRun summary: Delete a run description: Permanently delete a run and its associated data. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Runs responses: "200": description: Run deleted content: application/json: schema: type: object properties: success: type: boolean "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/runs/{runId}/permissions: parameters: - name: runId in: path required: true schema: type: string format: uuid description: Run ID get: operationId: getRunPermissions summary: Get run access permissions description: Returns the caller's role and scoped project/organization IDs for a run. tags: - Runs responses: "200": description: Permissions payload content: application/json: schema: $ref: "#/components/schemas/RunPermissionsResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to fetch permissions /api/runs/{runId}/status: parameters: - name: runId in: path required: true schema: type: string format: uuid description: Run ID get: operationId: getRunStatus summary: Get run status description: Quick status check for a run. Useful for polling in CI/CD pipelines. tags: - Runs responses: "200": description: Run status content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/runs/{runId}/stream: parameters: - name: runId in: path required: true schema: type: string format: uuid description: Run ID get: operationId: streamRunOutput summary: Stream run output (SSE) description: Stream live console output from a running job execution using Server-Sent Events. The stream includes heartbeat events and closes when the run completes. tags: - Runs responses: "200": description: SSE event stream content: text/event-stream: schema: type: string "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/runs/{runId}/cancel: parameters: - name: runId in: path required: true schema: type: string format: uuid description: Run ID post: operationId: cancelRun summary: Cancel a run description: Cancel a running or queued job execution. tags: - Runs responses: "200": description: Run cancelled content: application/json: schema: type: object properties: success: type: boolean message: type: string runId: type: string format: uuid "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/tests: get: operationId: listTests summary: List tests description: List all tests in the current project with optional search and type filters. tags: - Tests parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/Limit" - name: includeScript in: query schema: type: boolean description: Include decoded script content in each listed test. Defaults to false. - name: search in: query schema: type: string description: Search by title - name: type in: query schema: type: string enum: - browser - api - performance - database - custom description: "Filter by test type. Aliases: `playwright` → `browser`, `k6` → `performance`" - name: priority in: query schema: type: string enum: - low - medium - high description: Filter by priority. Any other value returns 400. responses: "200": description: Paginated list of tests content: application/json: schema: allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: $ref: "#/components/schemas/Test" "400": description: Invalid priority filter content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createTest summary: Create a test description: "Create a new test with a script. Supported types: `browser` (Playwright), `api`, `performance` (k6), `database`, `custom`." tags: - Tests requestBody: required: true content: application/json: schema: type: object properties: title: type: string example: Homepage Load Test script: type: string description: Test script content type: type: string enum: - browser - api - performance - database - custom default: browser description: "Test type. Aliases accepted: `playwright` → `browser`, `k6` → `performance`" description: type: string priority: type: string enum: - low - medium - high default: medium description: Defaults to `medium`. Any other value returns 400. required: - title responses: "201": description: Test created content: application/json: schema: type: object properties: success: type: boolean test: $ref: "#/components/schemas/Test" "400": description: Missing title or invalid priority content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" /api/tests/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Test ID get: operationId: getTest summary: Get test details description: Retrieve full details for a test including its script content. tags: - Tests responses: "200": description: Test details content: application/json: schema: $ref: "#/components/schemas/Test" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" parameters: - name: includeScript in: query schema: type: boolean description: Include decoded script content in the response. Defaults to true unless explicitly set to false. patch: operationId: updateTest summary: Update a test description: Update test title, script, description, type, or priority. Requires `test:update`, checked before the ID; for an authorized caller, a malformed ID returns 404. tags: - Tests requestBody: required: true content: application/json: schema: type: object properties: title: type: string script: type: string description: type: string type: type: string enum: - browser - api - performance - database - custom priority: type: string enum: - low - medium - high description: Test priority. Any other value returns 400. responses: "200": description: Test updated content: application/json: schema: $ref: "#/components/schemas/Test" "400": description: Invalid priority or body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteTest summary: Delete a test description: Delete a test. Fails if the test is in use by active jobs or synthetic monitors. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Tests responses: "200": description: Test deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string required: - success - message "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "409": description: Test is in use by jobs or synthetic monitors and cannot be deleted put: operationId: updateTestLegacyPut summary: Update a test using the legacy PUT alias description: Update test title, script, description, type, or priority. PUT is retained for CLI deploy and backward compatibility; interactive partial updates should prefer PATCH. Requires `test:update`, checked before the ID; for an authorized caller, a malformed ID returns 404. tags: - Tests requestBody: required: true content: application/json: schema: type: object properties: title: type: string script: type: string description: type: string type: type: string enum: - browser - api - performance - database - custom priority: type: string enum: - low - medium - high description: Test priority. Any other value returns 400. responses: "200": description: Test updated content: application/json: schema: $ref: "#/components/schemas/Test" "400": description: Invalid priority or body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/tests/{id}/tags: parameters: - name: id in: path required: true schema: type: string format: uuid description: Test ID get: operationId: getTestTags summary: Get test tags description: List all tags attached to a test. tags: - Tests responses: "200": description: Tags for the test content: application/json: schema: type: array items: $ref: "#/components/schemas/Tag" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" post: operationId: replaceTestTags summary: Replace test tags description: Replace all tags for a test with the provided list. tags: - Tests requestBody: required: true content: application/json: schema: type: object properties: tagIds: type: array items: type: string format: uuid required: - tagIds responses: "200": description: Updated tag list content: application/json: schema: type: array items: $ref: "#/components/schemas/Tag" "400": description: Invalid input "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteTestTag summary: Remove a tag from a test description: Remove a specific tag from a test. tags: - Tests requestBody: required: true content: application/json: schema: type: object properties: tagId: type: string format: uuid required: - tagId responses: "200": description: Tag removed content: application/json: schema: type: object properties: success: type: boolean "400": description: Invalid input "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/tests/{id}/execute: parameters: - name: id in: path required: true schema: type: string format: uuid description: Test ID post: operationId: executeTest summary: Execute a test description: Execute a single test immediately. Creates a run and enqueues the test for execution. For k6 performance tests, an optional `location` can target an enabled location code or `global` for unrestricted any-worker routing. tags: - Tests requestBody: content: application/json: schema: type: object properties: location: type: string description: Execution location for k6 performance tests. Use an enabled location code (for example `us-east`) or `global` for unrestricted any-worker routing. `global` is rejected when project location restrictions are enabled. responses: "200": description: Test execution started content: application/json: schema: type: object properties: runId: type: string format: uuid status: type: string enum: - running - queued position: type: integer minimum: 0 description: Queue position when the test is queued; omitted when it starts immediately. testType: type: string enum: - browser - api - performance - database - custom location: type: string description: Resolved execution location for performance tests; omitted for other test types. "401": $ref: "#/components/responses/Unauthorized" "402": description: Execution access denied "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": description: Execution rate limit exceeded /api/monitors: get: operationId: listMonitors summary: List monitors description: List all uptime and performance monitors in the current project. Request authentication credentials, request headers, and request bodies are omitted from config unless the caller has monitor:update permission. Users with update permission receive the full configuration for editing. Each item also includes its `tags`. tags: - Monitors parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/MonitorLimit" responses: "200": description: Paginated list of monitors content: application/json: schema: allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: allOf: - $ref: "#/components/schemas/Monitor" - type: object properties: tags: type: array items: $ref: "#/components/schemas/Tag" description: Tags attached to the monitor, ordered by name. "401": $ref: "#/components/responses/Unauthorized" post: operationId: createMonitor summary: Create a monitor description: Create a new uptime or performance monitor. tags: - Monitors requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MonitorCreateRequest" responses: "201": description: Monitor created content: application/json: schema: $ref: "#/components/schemas/Monitor" "400": description: Invalid monitor payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" put: operationId: updateMonitorByBodyId summary: Update a monitor (collection PUT) description: Compatibility update that requires `id` in the JSON body. Prefer `PATCH /api/monitors/{id}` or `PUT /api/monitors/{id}` for new integrations. The monitor must belong to the current project. tags: - Monitors requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MonitorCollectionUpdateRequest" responses: "200": description: Monitor updated content: application/json: schema: $ref: "#/components/schemas/Monitor" "400": description: Monitor ID missing or invalid payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/monitors/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitor summary: Get monitor details description: Retrieve full details for a monitor including recent check results. Request authentication credentials, request headers, and request bodies are omitted from config unless the caller has monitor:update permission. Users with update permission receive the full configuration for editing. tags: - Monitors responses: "200": description: Monitor details content: application/json: schema: $ref: "#/components/schemas/Monitor" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" patch: operationId: updateMonitor summary: Update a monitor description: Update monitor configuration. Only provided fields are changed. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Monitors requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MonitorUpdateRequest" responses: "200": description: Monitor updated content: application/json: schema: $ref: "#/components/schemas/Monitor" "400": description: Invalid monitor update payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteMonitor summary: Delete a monitor description: Permanently delete a monitor and its check history. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Monitors responses: "200": description: Monitor deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string required: - success - message "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" put: operationId: replaceMonitorConfiguration summary: Update a monitor configuration description: Update monitor configuration. Only provided fields are changed. PUT is retained for CLI deploy and backward compatibility; interactive partial updates should prefer PATCH. Resource IDs must be canonical UUIDs; malformed IDs return 404. tags: - Monitors requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MonitorUpdateRequest" responses: "200": description: Monitor updated content: application/json: schema: $ref: "#/components/schemas/Monitor" "400": description: Invalid monitor update payload "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/monitors/{id}/results: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitorResults summary: Get monitor check results description: Retrieve paginated check results for a monitor with optional date and location filters. tags: - Monitors parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/Limit" - name: date in: query schema: type: string format: date description: Filter results to a specific UTC date (`YYYY-MM-DD`). - name: location in: query schema: type: string description: Filter by execution location responses: "200": description: Check results content: application/json: schema: allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: $ref: "#/components/schemas/MonitorResult" "400": description: Invalid pagination or filter parameters "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/monitors/{id}/stats: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitorStats summary: Get monitor statistics description: Returns 24-hour and 30-day performance statistics. All-locations reads prefer a combined rollup per period and fall back to legacy location rollups for periods without one. Each statistics window uses retained raw checks only when no rollups exist. meta.source identifies aggregates, aggregates+raw_p95, aggregates+raw, or raw. tags: - Monitors responses: "200": description: Monitor statistics content: application/json: schema: $ref: "#/components/schemas/MonitorStats" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/variables: get: operationId: listVariables summary: List variables description: List all project variables for the current project. Secret values are redacted in the response. File-type variables include metadata such as type, fileName, fileSize, and mimeType. tags: - Variables responses: "200": description: List of variables content: application/json: schema: type: array items: $ref: "#/components/schemas/Variable" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createVariable summary: Create a variable description: Create a new text or secret project variable. File-type variables are managed through the project UI upload workflow rather than this public JSON endpoint. tags: - Variables requestBody: required: true content: application/json: schema: type: object properties: key: type: string example: API_BASE_URL minLength: 4 maxLength: 20 pattern: ^[A-Z][A-Z0-9_]*$ description: Uppercase letters, digits, and underscores only; cannot use the SUPERCHECK_ prefix or reserved system names. value: type: string example: https://api.example.com maxLength: 10000 isSecret: type: boolean default: false description: type: string required: - key - value responses: "201": description: Variable created content: application/json: schema: $ref: "#/components/schemas/Variable" "401": $ref: "#/components/responses/Unauthorized" /api/variables/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Variable ID get: operationId: getVariable summary: Get a variable description: Retrieve a single variable. Secret values are redacted, and file-type variables return metadata rather than file contents. tags: - Variables responses: "200": description: Variable details content: application/json: schema: $ref: "#/components/schemas/Variable" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" put: operationId: updateVariable summary: Update a variable description: Update an existing text or secret variable's key, value, secret flag, or description. File-type variables must be managed through the project UI upload workflow. tags: - Variables requestBody: required: true content: application/json: schema: type: object properties: key: type: string minLength: 4 maxLength: 20 pattern: ^[A-Z][A-Z0-9_]*$ description: Uppercase letters, digits, and underscores only; cannot use the SUPERCHECK_ prefix or reserved system names. value: type: string maxLength: 10000 isSecret: type: boolean description: type: string responses: "200": description: Variable updated content: application/json: schema: $ref: "#/components/schemas/Variable" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteVariable summary: Delete a variable description: Permanently remove an environment variable from the project. tags: - Variables responses: "200": description: Variable deleted "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/tags: get: operationId: listTags summary: List tags description: List all tags in the current project. tags: - Tags responses: "200": description: List of tags content: application/json: schema: type: array items: $ref: "#/components/schemas/Tag" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createTag summary: Create a tag description: Create a new tag for organizing tests, monitors, and other resources. tags: - Tags requestBody: required: true content: application/json: schema: type: object properties: name: type: string example: production color: type: string example: "#3B82F6" required: - name responses: "201": description: Tag created content: application/json: schema: $ref: "#/components/schemas/Tag" "401": $ref: "#/components/responses/Unauthorized" /api/tags/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Tag ID delete: operationId: deleteTag summary: Delete a tag description: Delete a tag. Resources using this tag will have it removed. tags: - Tags responses: "200": description: Tag deleted "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" get: operationId: getTag summary: Get a tag description: Return a single tag by ID. tags: - Tags responses: "200": description: Tag content: application/json: schema: $ref: "#/components/schemas/Tag" "400": description: Tag ID is required "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error put: operationId: updateTag summary: Update a tag description: Rename a tag or change its color. tags: - Tags requestBody: required: true content: application/json: schema: type: object required: - name properties: name: type: string color: type: string nullable: true responses: "200": description: Updated tag content: application/json: schema: $ref: "#/components/schemas/Tag" "400": description: Tag name is required "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/notification-providers: get: operationId: listNotificationProviders summary: List notification providers description: List all configured notification providers for the current project. tags: - Notifications responses: "200": description: List of notification providers content: application/json: schema: type: array items: $ref: "#/components/schemas/NotificationProvider" "401": $ref: "#/components/responses/Unauthorized" post: operationId: createNotificationProvider summary: Create a notification provider description: Create a new notification provider (email, Slack, webhook, Telegram, Discord, or Teams). tags: - Notifications requestBody: required: true content: application/json: schema: type: object properties: name: type: string example: Slack Alerts type: type: string enum: - email - slack - webhook - telegram - discord - teams config: type: object description: Provider-specific configuration (e.g. `webhookUrl` for Slack) required: - name - type - config responses: "201": description: Provider created content: application/json: schema: $ref: "#/components/schemas/NotificationProvider" "401": $ref: "#/components/responses/Unauthorized" /api/notification-providers/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Notification provider ID get: operationId: getNotificationProvider summary: Get notification provider details description: Retrieve configuration details of a notification provider. tags: - Notifications responses: "200": description: Provider details content: application/json: schema: $ref: "#/components/schemas/NotificationProvider" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" put: operationId: updateNotificationProvider summary: Update a notification provider description: Update notification provider name, type, or configuration. tags: - Notifications requestBody: required: true content: application/json: schema: type: object properties: name: type: string type: type: string config: type: object required: - name - type - config responses: "200": description: Provider updated content: application/json: schema: $ref: "#/components/schemas/NotificationProvider" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteNotificationProvider summary: Delete a notification provider description: Remove a notification provider configuration. tags: - Notifications responses: "200": description: Provider deleted "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" /api/notification-providers/test: post: operationId: testNotificationProvider summary: Send a test notification description: Send a test notification to verify provider configuration before saving. tags: - Notifications requestBody: required: true content: application/json: schema: type: object properties: type: type: string enum: - email - slack - webhook - telegram - discord - teams config: type: object required: - type - config responses: "200": description: Test result content: application/json: schema: type: object properties: success: type: boolean message: type: string error: type: string "401": $ref: "#/components/responses/Unauthorized" /api/alerts/history: get: operationId: getAlertHistory summary: Get alert history description: View the history of triggered alerts for the current project. tags: - Alerts parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/Limit" responses: "200": description: Alert history content: application/json: schema: oneOf: - type: array items: $ref: "#/components/schemas/AlertHistoryEntry" - allOf: - $ref: "#/components/schemas/PaginatedResponse" - type: object properties: data: type: array items: $ref: "#/components/schemas/AlertHistoryEntry" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Failed to fetch alert history post: operationId: createAlertHistory summary: Create an alert history entry description: Record an alert event (for example a manually created failure or recovery signal). Requires monitor manage permission. tags: - Alerts requestBody: required: true content: application/json: schema: type: object required: - type - message - target - targetType - provider properties: type: type: string message: type: string target: type: string targetType: type: string provider: type: string status: type: string nullable: true monitorId: type: string format: uuid nullable: true jobId: type: string format: uuid nullable: true errorMessage: type: string nullable: true responses: "201": description: Alert history entry created content: application/json: schema: $ref: "#/components/schemas/AlertHistoryEntry" "400": description: Missing required fields "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Internal server error /api/audit: get: operationId: getAuditLogs summary: Get audit logs description: View audit trail of organization actions. Requires admin permissions. tags: - Audit parameters: - $ref: "#/components/parameters/Page" - $ref: "#/components/parameters/Limit" - name: action in: query schema: type: string description: Filter by action type responses: "200": description: Audit log entries content: application/json: schema: $ref: "#/components/schemas/AuditResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Failed to fetch audit logs /api/status-pages: get: operationId: listStatusPages summary: List status pages description: Fetch status pages for the current project. tags: - Status Pages responses: "200": description: Status page list content: application/json: schema: $ref: "#/components/schemas/StatusPageListResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Failed to fetch status pages post: operationId: createStatusPage summary: Create a status page tags: - Status Pages description: Create a status page in the current project. Requires `status_page:create`. The page starts as a `draft` and its `subdomain` is generated by the server; sending `subdomain` or `customDomainVerified` returns 400. Unknown body fields are rejected. If your account allows it, creation succeeds; otherwise a 403 explains the limit that was reached. A 429 means too many concurrent create requests - retry shortly. requestBody: required: true content: application/json: schema: type: object additionalProperties: false properties: name: type: string minLength: 1 maxLength: 255 headline: type: string maxLength: 255 pageDescription: type: string maxLength: 2000 required: - name responses: "201": description: Created status page content: application/json: schema: type: object properties: statusPage: $ref: "#/components/schemas/StatusPage" "400": description: Invalid body, or a server-managed field was sent content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": description: Insufficient permissions, or the number of status pages your account allows has been reached content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "429": description: Too many concurrent requests content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Failed to create status page content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/status-pages/check: get: operationId: checkStatusPageSubdomain summary: Verify that a status page subdomain is published description: Verify that a status page subdomain is published and return its ID. tags: - Status Pages security: [] parameters: - name: subdomain in: query required: true schema: type: string description: Status page subdomain responses: "200": description: Status page lookup content: application/json: schema: type: object properties: id: type: string format: uuid status: type: string "400": description: Subdomain parameter is required "404": $ref: "#/components/responses/NotFound" post: operationId: checkStatusPageSubdomainPost summary: Verify that a status page subdomain is published (POST) description: Verify that a status page subdomain is published and return its ID. Public endpoint (no authentication required). tags: - Status Pages security: [] requestBody: required: true content: application/json: schema: type: object required: - subdomain properties: subdomain: type: string responses: "200": description: Status page lookup content: application/json: schema: type: object properties: id: type: string format: uuid status: type: string "400": description: Invalid request "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/status-pages/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID get: operationId: getStatusPage summary: Get status page details description: Fetch a status page with components, monitors, and permissions. tags: - Status Pages responses: "200": description: Status page details content: application/json: schema: $ref: "#/components/schemas/StatusPageDetailResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to fetch status page delete: operationId: deleteStatusPage summary: Delete a status page description: Permanently deletes a status page and all its components. tags: - Status Pages responses: "200": description: Status page deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string required: - success - message "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" put: operationId: updateStatusPage summary: Update a status page tags: - Status Pages description: >- Update settings and/or status of a status page. Requires `status_page:update`. The body is strict: unknown fields, `subdomain` and `customDomainVerified` return 400, and an empty body returns 400 (`No fields to update`). Order of work: when `status` is `published`, publish preconditions are checked first and nothing is written if they fail (the page must be accessible to your account and have at least one public component, otherwise 403 or 400). Then settings are saved, then the status is changed. If the status change fails after settings were saved, the error message says so. Custom domains: setting a non-empty `customDomain` that differs from the current one resets verification and requires the feature to be available for your account (403 if not), a deployment configured for custom domains (400), a hostname outside the platform status page domain (400) and not used by another page (409). requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/StatusPageUpdateRequest" responses: "200": description: Updated status page content: application/json: schema: type: object properties: statusPage: $ref: "#/components/schemas/StatusPage" "400": description: Invalid body, publish precondition failed, or domain rule violated content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": description: Insufficient permissions, or the feature or action is not available for your account content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": $ref: "#/components/responses/NotFound" "409": description: Custom domain already in use by another status page content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Failed to update status page content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/status-pages/{id}/upload: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID post: operationId: uploadStatusPageAsset summary: Upload status page assets description: Upload favicon, logo, or cover image for a status page. tags: - Status Pages requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary type: type: string enum: - favicon - logo - cover required: - file - type responses: "200": description: Upload successful content: application/json: schema: type: object properties: success: type: boolean message: type: string url: type: string s3Key: type: string type: type: string "400": description: Invalid upload payload "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to upload file /api/status-pages/{id}/rss: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID get: operationId: getStatusPageRss summary: Get status page RSS feed description: Returns an RSS feed for a published status page. tags: - Status Pages security: [] responses: "200": description: RSS feed content: application/rss+xml: schema: type: string "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to generate RSS feed /api/validate-script: post: operationId: validateScript summary: Validate a test script description: Check script syntax, size and statement limits, and Playwright or k6 compatibility. Validation provides submission feedback, not a runtime security boundary. tags: - Tests requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ValidationScriptRequest" responses: "200": description: Script is valid content: application/json: schema: $ref: "#/components/schemas/ValidationScriptSuccessResponse" "400": description: Script failed validation content: application/json: schema: $ref: "#/components/schemas/ValidationScriptErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "429": description: Too many validation requests; retry after the Retry-After interval "500": description: Validation service error /api/monitors/{id}/status: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID patch: operationId: updateMonitorStatus summary: Update monitor status description: Pause, resume, or otherwise set a monitor's status (for example `paused` or `maintenance`). Requires monitor manage or update permission. Automated status changes from checks are handled separately. Read current monitor status with `GET /api/monitors/{id}`; this route does not support GET. tags: - Monitors requestBody: required: true content: application/json: schema: type: object required: - status properties: status: type: string enum: - up - down - paused - pending - maintenance - error responses: "200": description: Monitor status updated content: application/json: schema: type: object properties: success: type: boolean id: type: string format: uuid status: type: string enum: - up - down - paused - pending - maintenance - error updatedAt: type: string format: date-time "400": description: Invalid status value "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/monitors/{id}/notifications: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitorNotifications summary: List monitor notification links description: Return the notification providers linked to a monitor. tags: - Monitors responses: "200": description: Linked notification providers content: application/json: schema: type: array items: $ref: "#/components/schemas/MonitorNotificationLink" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error post: operationId: createMonitorNotification summary: Link a notification provider to a monitor description: Attach a notification provider to a monitor. The provider must belong to the same project as the monitor. tags: - Monitors requestBody: required: true content: application/json: schema: type: object required: - notificationProviderId properties: notificationProviderId: type: string format: uuid responses: "201": description: Notification link created content: application/json: schema: $ref: "#/components/schemas/MonitorNotificationLink" "400": description: Missing notification provider ID "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": description: Monitor or provider not found "409": description: Monitor already linked to this provider "500": description: Internal server error delete: operationId: deleteMonitorNotification summary: Unlink a notification provider from a monitor description: Remove a notification provider link from a monitor. tags: - Monitors parameters: - name: notificationProviderId in: query required: true schema: type: string format: uuid description: Notification provider to unlink responses: "200": description: Notification link removed content: application/json: schema: type: object properties: success: type: boolean "400": description: Missing notification provider ID "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/monitors/{id}/permissions: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitorPermissions summary: Get monitor permissions description: Return the current user's effective permissions for a monitor. tags: - Monitors responses: "200": description: Effective permissions content: application/json: schema: $ref: "#/components/schemas/MonitorPermissionsResponse" "400": description: Invalid monitor ID "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/monitors/{id}/location-stats: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID - name: days in: query required: false schema: type: integer minimum: 1 maximum: 90 default: 7 description: Number of days to look back (1-90) get: operationId: getMonitorLocationStats summary: Get monitor location stats description: Return per-location aggregated statistics (uptime, response times) for a monitor over the requested window. tags: - Monitors responses: "200": description: Per-location statistics content: application/json: schema: type: array items: $ref: "#/components/schemas/MonitorLocationStats" "400": description: Days must be between 1 and 90 "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/status-pages/{id}/badge: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID get: operationId: getStatusPageBadge summary: Get status page badge description: Returns a public SVG status badge. Successful responses are cached for five minutes. tags: - Status Pages security: [] parameters: - name: style in: query schema: type: string enum: - flat - flat-square default: flat - name: label in: query schema: type: string maxLength: 64 default: status responses: "200": description: SVG status badge content: image/svg+xml: schema: type: string "400": description: Invalid status page ID "404": $ref: "#/components/responses/NotFound" "500": description: Failed to generate badge /api/status-pages/{id}/ical: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID get: operationId: getStatusPageIcal summary: Get status page calendar feed description: Returns an RFC 5545 iCalendar feed for a published status page. tags: - Status Pages security: [] responses: "200": description: iCalendar feed content: text/calendar: schema: type: string "400": description: Invalid status page ID "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to generate calendar feed /api/organizations: get: operationId: listOrganizations summary: Get assigned organization description: "Returns the selected project's host organization, or the default account organization when no project is selected. Users cannot create or switch organizations directly; they can select projects from their account and invited teams. The existing list response is preserved for compatibility: data contains zero or one organization and activeOrganizationId identifies that organization; it is not a directory of all team memberships." tags: - Organizations responses: "200": description: Organizations for the current user content: application/json: schema: type: object properties: success: type: boolean data: type: array items: $ref: "#/components/schemas/OrganizationSummary" activeOrganizationId: type: string format: uuid nullable: true "401": $ref: "#/components/responses/Unauthorized" "500": description: Internal server error /api/organizations/current: get: operationId: getCurrentOrganization summary: Get the active organization description: Returns the organization from the current auth context. Requires org_admin or org_owner. tags: - Organizations responses: "200": description: Active organization content: application/json: schema: type: object properties: success: type: boolean data: $ref: "#/components/schemas/OrganizationCurrent" "400": description: No active organization found "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error /api/organizations/stats: get: operationId: getOrganizationStats summary: Get organization usage stats description: Counts of projects, jobs, tests, monitors, runs, and members for the active organization. Requires org_admin or org_owner. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Organization stats content: application/json: schema: type: object properties: success: type: boolean data: $ref: "#/components/schemas/OrganizationStats" "400": description: No active organization found "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Internal server error security: - sessionCookie: [] /api/organizations/{id}: parameters: - name: id in: path required: true schema: type: string description: Organization ID get: operationId: getOrganization summary: Get organization details description: Returns organization details, the caller's role, and project/member counts. Requires membership. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Organization details content: application/json: schema: type: object properties: success: type: boolean organization: $ref: "#/components/schemas/OrganizationDetail" "401": $ref: "#/components/responses/Unauthorized" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error security: - sessionCookie: [] put: operationId: updateOrganization summary: Update organization description: Update the organization name (2–50 characters after trim). Optional slug, logo, and metadata. Requires org_admin or org_owner. Browser updates require a same-origin request; CLI tokens retain their existing authorization. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/OrganizationUpdateRequest" responses: "200": description: Organization updated content: application/json: schema: type: object properties: success: type: boolean organization: type: object "400": description: Invalid organization name "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error security: - sessionCookie: [] delete: operationId: deleteOrganization summary: Delete organization description: Owner only. Only empty organizations without protected dependencies can be deleted. Selected browser session references are cleared atomically. Organizations containing projects or protected dependencies return 409; contact an administrator or support for safe removal. Browser mutations require a same-origin request; CLI tokens retain their existing authorization. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Organization deleted content: application/json: schema: type: object properties: success: type: boolean message: type: string "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "409": description: Organization contains projects or protected dependencies; removal requires administrator or support assistance. "500": description: Internal server error security: - sessionCookie: [] /api/organizations/members: get: operationId: listOrganizationMembers summary: List members and invitations description: List members (with project assignments), pending/expired invitations, and the current user's org role. Requires org_admin or org_owner. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Members and invitations content: application/json: schema: type: object properties: success: type: boolean data: type: object properties: members: type: array items: $ref: "#/components/schemas/OrganizationMember" invitations: type: array items: $ref: "#/components/schemas/OrganizationInvitation" currentUserRole: type: string "400": description: No active organization found "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Internal server error security: - sessionCookie: [] /api/organizations/members/{memberId}: parameters: - name: memberId in: path required: true schema: type: string description: User ID of the organization member put: operationId: updateOrganizationMember summary: Update member role and projects description: Update a member's role and project assignments. Cannot change the owner, your own role, or (as org_admin) another org_admin. Only org_owner can assign org_admin. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/OrganizationMemberUpdateRequest" responses: "200": description: Member updated content: application/json: schema: type: object properties: success: type: boolean message: type: string data: type: object properties: memberId: type: string newRole: type: string oldRole: type: string "400": description: Invalid role or project assignments "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error security: - sessionCookie: [] delete: operationId: removeOrganizationMember summary: Remove a member description: Remove a member and their project assignments in this organization. Cannot remove the owner or yourself. Only org_owner can remove org_admin members. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Member removed content: application/json: schema: type: object properties: success: type: boolean message: type: string data: type: object properties: memberId: type: string removedRole: type: string "400": description: No active organization found "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error security: - sessionCookie: [] /api/organizations/members/invite: post: operationId: inviteOrganizationMember summary: Invite a member description: Create a pending invitation and send email. Counts accepted invitations per user (`INVITE_RATE_LIMIT_MAX`, default 10/hour). Authorization, invalid or duplicate requests, and rejected inserts do not consume quota. Requires org_admin or org_owner. Only org_owner can invite org_admin. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/OrganizationInviteRequest" responses: "200": description: Invitation created content: application/json: schema: type: object properties: success: type: boolean data: type: object properties: id: type: string email: type: string role: type: string status: type: string expiresAt: type: string format: date-time inviteLink: type: string emailSent: type: boolean "400": description: Invalid invite payload or user already a member "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "429": description: Rate limit exceeded "500": description: Internal server error security: - sessionCookie: [] /api/organizations/members/invite/{invitationId}: parameters: - name: invitationId in: path required: true schema: type: string description: Invitation ID delete: operationId: cancelOrganizationInvitation summary: Cancel an invitation description: Cancel a pending invitation. Requires org_admin or org_owner. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Invitation cancelled content: application/json: schema: type: object properties: success: type: boolean message: type: string "400": description: Invitation is not pending "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Internal server error security: - sessionCookie: [] post: operationId: resendOrganizationInvitation summary: Resend an invitation description: Resend a pending invitation email. Rate limited (5/hour). Expired invitations have expiry extended by 7 days. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Invitation resent content: application/json: schema: type: object properties: success: type: boolean message: type: string data: type: object properties: emailSent: type: boolean expiryExtended: type: boolean "400": description: Invitation is not pending "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "429": description: Rate limit exceeded "500": description: Internal server error security: - sessionCookie: [] /api/organizations/invitations: get: operationId: listOrganizationInvitations summary: List invitations description: List invitations for the active organization. Requires org_admin or org_owner. Requires an interactive browser session. Project-scoped CLI tokens receive 403. tags: - Organizations responses: "200": description: Invitations content: application/json: schema: type: object properties: success: type: boolean data: type: array items: $ref: "#/components/schemas/OrganizationInvitation" "400": description: No active organization found "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Internal server error security: - sessionCookie: [] /api/locations/metadata: get: operationId: listLocationMetadata summary: List historical location display metadata description: Requires authentication. Returns display fields for enabled and inactive locations visible in the current hosting mode. Does not include worker status, administrative settings, or execution availability. Use /api/locations for execution choices. tags: - System responses: "200": description: Display metadata content: application/json: schema: type: object properties: success: type: boolean data: type: array items: $ref: "#/components/schemas/LocationDisplayMetadata" "401": $ref: "#/components/responses/Unauthorized" /api/auth/device/code: post: operationId: requestDeviceCode summary: Start a browser login for the CLI description: RFC 8628 device authorization request. Public; returns a short user code to confirm in the browser. No credential is returned. Available only when the server enables browser login (`DEVICE_AUTH_ENABLED=true`); otherwise returns 503 `device_auth_disabled`. tags: - Authentication requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: client_id: type: string enum: - supercheck-cli client_name: type: string maxLength: 64 cli_version: type: string maxLength: 32 hostname: type: string maxLength: 64 required: - client_id responses: "200": description: Device authorization started. content: application/json: schema: type: object properties: device_code: type: string description: Secret polled by the CLI. Never display or log it. user_code: type: string example: BCDF-GHJK verification_uri: type: string format: uri verification_uri_complete: type: string format: uri expires_in: type: integer example: 900 interval: type: integer example: 5 required: - device_code - user_code - verification_uri - expires_in - interval "400": description: Malformed request body. content: application/json: schema: type: object properties: error: type: string enum: - invalid_request required: - error "401": description: Unknown client id. content: application/json: schema: type: object properties: error: type: string enum: - invalid_client required: - error "429": description: Too many requests. "500": description: Server error. content: application/json: schema: type: object properties: error: type: string enum: - server_error required: - error "503": description: Browser login is disabled on this server. content: application/json: schema: type: object properties: error: type: string enum: - device_auth_disabled required: - error security: [] /api/auth/device/token: post: operationId: exchangeDeviceCode summary: Exchange an approved device code for a CLI key description: RFC 8628 device access token request. Poll no faster than the returned `interval`. On success a project-scoped CLI key (90-day expiry) is created and returned exactly once; a lost response cannot be recovered, revoke the unused key under CLI tokens and log in again. tags: - Authentication requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object properties: grant_type: type: string enum: - urn:ietf:params:oauth:grant-type:device_code client_id: type: string enum: - supercheck-cli device_code: type: string required: - grant_type - client_id - device_code responses: "200": description: "Approved. Response is not cacheable (`Cache-Control: no-store`)." content: application/json: schema: type: object properties: access_token: type: string description: Project-scoped CLI key (`sck_live_*`). token_type: type: string enum: - Bearer expires_in: type: integer context: type: object description: Non-secret user, organization and project the key belongs to. required: - access_token - token_type - expires_in "400": description: OAuth 2.0 device-authorization error (RFC 8628 §3.5) content: application/json: schema: type: object properties: error: type: string enum: - authorization_pending - slow_down - access_denied - expired_token - invalid_grant - invalid_client - invalid_request - unsupported_grant_type - token_limit_reached - device_auth_disabled - rate_limited interval: type: integer description: Minimum seconds before the next poll, when applicable. required: - error "401": description: OAuth 2.0 device-authorization error (RFC 8628 §3.5) content: application/json: schema: type: object properties: error: type: string enum: - authorization_pending - slow_down - access_denied - expired_token - invalid_grant - invalid_client - invalid_request - unsupported_grant_type - token_limit_reached - device_auth_disabled - rate_limited interval: type: integer description: Minimum seconds before the next poll, when applicable. required: - error "409": description: OAuth 2.0 device-authorization error (RFC 8628 §3.5) content: application/json: schema: type: object properties: error: type: string enum: - authorization_pending - slow_down - access_denied - expired_token - invalid_grant - invalid_client - invalid_request - unsupported_grant_type - token_limit_reached - device_auth_disabled - rate_limited interval: type: integer description: Minimum seconds before the next poll, when applicable. required: - error "429": description: Polling too fast or rate limited. content: application/json: schema: type: object properties: error: type: string enum: - slow_down interval: type: integer required: - error "500": description: Server error. content: application/json: schema: type: object properties: error: type: string enum: - server_error required: - error "503": description: Browser login is disabled on this server. content: application/json: schema: type: object properties: error: type: string enum: - device_auth_disabled required: - error security: [] /api/auth/device/approve: post: operationId: approveDeviceCode summary: Approve a CLI login (browser session only) description: Records consent for one project. Requires a signed-in browser session and a same-origin request; no key is created until the CLI exchanges the code. tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: user_code: type: string project_id: type: string format: uuid required: - user_code - project_id responses: "200": description: Recorded. "400": description: Invalid request. "401": $ref: "#/components/responses/Unauthorized" "403": description: Cross-origin request, or the signed-in user may not create CLI keys in that project. "404": description: Unknown code. "409": description: Code already handled. "410": description: Code expired. "429": description: Too many requests. "500": description: Server error. "503": description: Browser login is disabled. security: - sessionCookie: [] /api/auth/device/deny: post: operationId: denyDeviceCode summary: Deny a CLI login (browser session only) description: Terminally denies the request; also revokes an approval that has not yet been exchanged. tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: user_code: type: string required: - user_code responses: "200": description: Recorded. "400": description: Invalid request. "401": $ref: "#/components/responses/Unauthorized" "403": description: Cross-origin request. "404": description: Unknown code. "409": description: Code already handled. "410": description: Code expired. "429": description: Too many requests. "500": description: Server error. "503": description: Browser login is disabled. security: - sessionCookie: [] /api/organizations/leave: post: tags: - Organizations summary: Leave the current organization operationId: leaveOrganization description: Leave the active organization as a non-owner using an interactive browser session and a same-origin request. Removes the caller's membership and project assignments, clears this organization's selected context from all their sessions, and records member_left in the audit log. Owners must transfer ownership or delete the organization. Project-scoped CLI tokens receive 403. The supplied organization ID must match the active organization resolved from the session; stale confirmations receive 409. security: - sessionCookie: [] responses: "200": description: Organization left; reload to select a remaining membership or complete personal setup. content: application/json: schema: type: object properties: success: type: boolean data: type: object properties: organizationId: type: string format: uuid "400": description: No active organization "401": description: Authentication required "403": description: Owner, CLI token, or cross-origin request "404": description: Membership no longer exists "409": description: The active organization changed; reload before confirming. "500": description: Failed to leave organization requestBody: required: true content: application/json: schema: type: object required: - organizationId additionalProperties: false properties: organizationId: type: string format: uuid description: The organization being confirmed; must match the active session organization. /api/requirements: get: operationId: listRequirements summary: List requirements tags: - Requirements description: List requirements in the current project, newest first. Requires `requirement:view`. Each item includes the linked test IDs (`testIds`) and tag names (`tagNames`) so clients do not need a per-row detail request. The response also repeats the items under `requirements` for backward compatibility. parameters: - name: page in: query schema: type: integer minimum: 1 maximum: 100000 default: 1 description: Page number. Out-of-range values are clamped. - name: pageSize in: query schema: type: integer minimum: 1 maximum: 500 default: 500 description: Items per page. Values outside 1..500 are clamped; the default is 500. - name: search in: query schema: type: string description: Match against title or description (substring). - name: priority in: query schema: type: string enum: - low - medium - high description: Filter by priority. - name: status in: query schema: type: string enum: - covered - failing - missing description: Filter by coverage status. Requirements with no computed coverage count as `missing`. responses: "200": description: Requirements page content: application/json: schema: type: object properties: data: type: array items: $ref: "#/components/schemas/RequirementListItem" requirements: type: array items: $ref: "#/components/schemas/RequirementListItem" description: Alias of `data`. total: type: integer page: type: integer pageSize: type: integer "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Failed to fetch requirements content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" post: operationId: createRequirement summary: Create a requirement tags: - Requirements description: Create a requirement, optionally with tags (by name) and linked tests. Requires `requirement:create`. Unknown body fields are rejected with 400. Linked tests are checked before anything is written, so a failed request leaves nothing behind. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RequirementCreateRequest" responses: "201": description: Created requirement content: application/json: schema: $ref: "#/components/schemas/RequirementResponse" "400": description: Invalid request body or JSON content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "409": description: Requirement id is already in use content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Failed to create requirement content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/requirements/{id}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Requirement ID get: operationId: getRequirement summary: Get a requirement tags: - Requirements description: Fetch one requirement with tag names, linked test IDs and coverage. Requires `requirement:view`. Malformed IDs return 404. responses: "200": description: Requirement content: application/json: schema: $ref: "#/components/schemas/RequirementResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" put: operationId: updateRequirement summary: Update a requirement tags: - Requirements description: Partially update a requirement. Requires `requirement:update`. When `tags` or `testIds` is present it replaces the whole set. Unknown body fields are rejected with 400. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RequirementUpdateRequest" responses: "200": description: Updated requirement content: application/json: schema: $ref: "#/components/schemas/RequirementResponse" "400": description: Invalid request body or JSON content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" "500": description: Failed to update requirement content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" delete: operationId: deleteRequirement summary: Delete a requirement tags: - Requirements description: Delete a requirement. Requires `requirement:delete`. responses: "200": description: Requirement deleted content: application/json: schema: type: object properties: success: type: boolean "400": description: Request could not be completed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/requirements/{id}/tests: parameters: - name: id in: path required: true schema: type: string format: uuid description: Requirement ID get: operationId: listRequirementTests summary: List tests linked to a requirement tags: - Requirements description: List the tests linked to a requirement. Requires `requirement:view`. responses: "200": description: Linked tests content: application/json: schema: type: object properties: tests: type: array items: $ref: "#/components/schemas/RequirementLinkedTest" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" post: operationId: linkRequirementTests summary: Link tests to a requirement tags: - Requirements description: Add tests to a requirement, keeping existing links. Requires `requirement:update`. Tests must belong to the current project; duplicates in the body are ignored. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RequirementTestIdsRequest" responses: "200": description: Requirement with its updated links content: application/json: schema: $ref: "#/components/schemas/RequirementResponse" "400": description: Invalid request body or JSON content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: unlinkRequirementTests summary: Unlink tests from a requirement tags: - Requirements description: 'Remove links between a requirement and tests. Requires `requirement:update`. Pass a single test with the `testId` query parameter, or several in a JSON body `{ "testIds": [...] }`. Unlinking a test that is not linked is a no-op.' parameters: - name: testId in: query schema: type: string format: uuid description: Single test to unlink. When present, the request body is ignored. requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/RequirementTestIdsRequest" responses: "200": description: Requirement with its updated links content: application/json: schema: $ref: "#/components/schemas/RequirementResponse" "400": description: Invalid request body or JSON content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/requirements/export: get: operationId: exportRequirementsCsv summary: Export requirements as CSV tags: - Requirements description: "Download all requirements of the current project as `requirements.csv`. Requires `requirement:view`. Columns: ID, Title, Description, Priority, Status, Tags, Linked Tests, Passed Tests, Failed Tests, External ID, External URL, Created At. Cells that start with `=`, `+`, `-`, `@`, a tab or a carriage return are prefixed with a single quote (`'`) so spreadsheets do not evaluate them as formulas." responses: "200": description: CSV file headers: Content-Disposition: schema: type: string description: '`attachment; filename="requirements.csv"`' content: text/csv: schema: type: string "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "500": description: Failed to export requirements content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/status-pages/{id}/components: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID get: operationId: listStatusPageComponents summary: List status page components tags: - Status Pages description: List components of a status page ordered by position. Requires `status_page:view`. responses: "200": description: Components content: application/json: schema: type: object properties: components: type: array items: $ref: "#/components/schemas/StatusPageComponentDto" "400": description: Invalid status page ID content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" post: operationId: createStatusPageComponent summary: Create a status page component tags: - Status Pages description: Add a component to a status page. Requires `status_page:update`. Unknown body fields are rejected with 400. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/StatusPageComponentCreateRequest" responses: "201": description: Created component content: application/json: schema: type: object properties: component: $ref: "#/components/schemas/StatusPageComponentDto" "400": description: Invalid body or IDs, or a monitor/service is not found in this project content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/status-pages/{id}/components/{componentId}: parameters: - name: id in: path required: true schema: type: string format: uuid description: Status page ID - name: componentId in: path required: true schema: type: string format: uuid description: Component ID put: operationId: updateStatusPageComponent summary: Update a status page component tags: - Status Pages description: Partially update a component. Requires `status_page:update`. When `monitorIds` is present the monitor links are replaced atomically. If `monitorIds` lists at least one monitor and `status` is omitted, the status is re-derived from the linked monitors; clearing all monitors keeps the current status. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/StatusPageComponentUpdateRequest" responses: "200": description: Updated component content: application/json: schema: type: object properties: component: $ref: "#/components/schemas/StatusPageComponentDto" "400": description: Invalid body or IDs, or a monitor/service is not found in this project content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteStatusPageComponent summary: Delete a status page component tags: - Status Pages description: Delete a component. Requires `status_page:delete`. responses: "200": description: Component deleted content: application/json: schema: type: object properties: success: type: boolean "400": description: Invalid ID format content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" /api/monitors/{id}/tags: parameters: - name: id in: path required: true schema: type: string format: uuid description: Monitor ID get: operationId: getMonitorTags summary: Get monitor tags tags: - Monitors description: List tags attached to a monitor. Requires `monitor:view`. Malformed IDs return 404. responses: "200": description: Tags attached to the monitor, ordered by name content: application/json: schema: type: object properties: tags: type: array items: $ref: "#/components/schemas/Tag" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" post: operationId: replaceMonitorTags summary: Replace monitor tags tags: - Monitors description: Replace all tags of a monitor with the given set (atomic; an empty array removes all tags). Requires `monitor:update`. At most 10 tags per monitor; tags must exist in the current project and duplicates are rejected. requestBody: required: true content: application/json: schema: type: object properties: tagIds: type: array maxItems: 10 items: type: string format: uuid required: - tagIds responses: "200": description: Updated tag list content: application/json: schema: type: object properties: tags: type: array items: $ref: "#/components/schemas/Tag" "400": description: Invalid, duplicate or inaccessible tag IDs, or more than 10 tags content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" delete: operationId: deleteMonitorTag summary: Remove a tag from a monitor tags: - Monitors description: Remove one tag from a monitor. Requires `monitor:update`. requestBody: required: true content: application/json: schema: type: object properties: tagId: type: string format: uuid required: - tagId responses: "200": description: Tag removed content: application/json: schema: type: object properties: success: type: boolean "400": description: Tag ID is required content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "401": $ref: "#/components/responses/Unauthorized" "403": $ref: "#/components/responses/Forbidden" "404": $ref: "#/components/responses/NotFound" components: securitySchemes: bearerAuth: type: http scheme: bearer description: Project-scoped CLI token (`sck_live_*` or `sck_test_*`) for documented API operations that accept bearer authentication. Interactive browser operations may require a session cookie. Trigger keys (`sck_trigger_*` / legacy `job_*`) are accepted only by job trigger endpoints. sessionCookie: type: apiKey in: cookie name: better-auth.session_token description: Interactive Better Auth browser session. Secure deployments may use the `__Secure-` cookie prefix. parameters: Page: name: page in: query schema: type: integer default: 1 minimum: 1 example: 1 description: Page number for pagination Limit: name: limit in: query schema: type: integer default: 20 minimum: 1 maximum: 100 example: 20 description: Items per page JobLimit: name: limit in: query schema: type: integer default: 100 minimum: 1 maximum: 100 example: 100 description: Jobs per page MonitorLimit: name: limit in: query schema: type: integer default: 50 minimum: 1 maximum: 100 example: 50 description: Monitors per page. For backward compatibility, omitting both page and limit returns all matching monitors. RunLimit: name: limit in: query schema: type: integer default: 1000 minimum: 1 maximum: 1000 example: 100 description: Runs per page. Omitting limit returns up to 1000 matching runs. responses: Unauthorized: description: Authentication required or token invalid content: application/json: schema: type: object properties: error: type: string example: Unauthorized NotFound: description: Resource not found content: application/json: schema: type: object properties: error: type: string example: Not found Forbidden: description: Insufficient permissions content: application/json: schema: type: object properties: error: type: string schemas: PaginatedResponse: type: object properties: pagination: type: object properties: total: type: integer page: type: integer limit: type: integer totalPages: type: integer hasNextPage: type: boolean hasPrevPage: type: boolean Job: type: object properties: id: type: string format: uuid name: type: string description: type: string nullable: true cronSchedule: type: string nullable: true status: type: string enum: - pending - running - passed - failed - error alertConfig: anyOf: - $ref: "#/components/schemas/JobAlertConfig" - type: "null" description: Alert configuration for this job tests: type: array items: $ref: "#/components/schemas/Test" description: Tests associated with this job lastRun: anyOf: - $ref: "#/components/schemas/JobLastRun" - type: "null" testCount: type: integer nullable: true lastRunAt: type: string format: date-time nullable: true nextRunAt: type: string format: date-time nullable: true scheduledJobId: type: string nullable: true jobType: type: string enum: - playwright - k6 nullable: true organizationId: type: string format: uuid nullable: true projectId: type: string format: uuid nullable: true createdByUserId: type: string format: uuid nullable: true createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true Run: type: object properties: id: type: string format: uuid jobId: type: string format: uuid nullable: true jobName: type: string nullable: true jobType: type: string enum: - playwright - k6 nullable: true status: type: string enum: - queued - running - passed - failed - error - blocked trigger: type: string enum: - manual - remote - schedule duration: type: string description: Formatted duration string nullable: true durationMs: type: integer description: Duration in milliseconds nullable: true startedAt: type: string format: date-time nullable: true completedAt: type: string format: date-time nullable: true logs: type: string nullable: true errorDetails: type: string nullable: true reportUrl: type: string nullable: true description: URL to the run report testCount: type: integer nullable: true location: type: string nullable: true projectId: type: string format: uuid nullable: true organizationId: type: string format: uuid nullable: true RunPermissionsResponse: type: object properties: success: type: boolean data: type: object properties: userRole: type: string projectId: type: string format: uuid organizationId: type: string format: uuid StatusPage: type: object properties: id: type: string format: uuid name: type: string subdomain: type: string status: type: string pageDescription: type: string nullable: true allowRssFeed: type: boolean faviconLogo: type: string nullable: true transactionalLogo: type: string nullable: true heroCover: type: string nullable: true createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true additionalProperties: true StatusPageComponentMonitor: type: object properties: id: type: string format: uuid name: type: string type: type: string status: type: string target: type: string weight: type: number nullable: true StatusPageComponent: type: object properties: id: type: string format: uuid name: type: string description: type: string nullable: true position: type: integer nullable: true createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true monitors: type: array items: $ref: "#/components/schemas/StatusPageComponentMonitor" monitorIds: type: array items: type: string format: uuid additionalProperties: true StatusPageDetailResponse: type: object properties: statusPage: $ref: "#/components/schemas/StatusPage" components: type: array items: $ref: "#/components/schemas/StatusPageComponent" monitors: type: array items: type: object properties: id: type: string format: uuid name: type: string type: type: string status: type: string canUpdate: type: boolean StatusPageListResponse: type: object properties: data: type: array items: $ref: "#/components/schemas/StatusPage" pagination: type: object properties: total: type: integer page: type: integer limit: type: integer totalPages: type: integer AlertHistoryEntry: type: object properties: id: type: string format: uuid targetType: type: string targetId: type: string targetName: type: string type: type: string message: type: string status: type: string timestamp: type: string format: date-time notificationProvider: type: string metadata: type: object properties: errorMessage: type: string nullable: true additionalProperties: true AuditLogEntry: type: object properties: id: type: string format: uuid action: type: string details: type: object nullable: true createdAt: type: string format: date-time user: type: object properties: id: type: string format: uuid name: type: string nullable: true email: type: string nullable: true AuditResponse: type: object properties: success: type: boolean data: type: object properties: logs: type: array items: $ref: "#/components/schemas/AuditLogEntry" pagination: type: object properties: currentPage: type: integer totalPages: type: integer totalCount: type: integer limit: type: integer hasNext: type: boolean hasPrev: type: boolean filters: type: object properties: actions: type: array items: type: string Test: type: object properties: id: type: string format: uuid name: type: string nullable: true title: type: string description: type: string nullable: true priority: type: string enum: - low - medium - high description: Test priority type: type: string enum: - browser - api - performance - database - custom description: Test type. `browser` = Playwright, `performance` = k6 script: type: string nullable: true description: Test script content projectId: type: string format: uuid nullable: true organizationId: type: string format: uuid nullable: true tags: type: array items: $ref: "#/components/schemas/Tag" createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true Monitor: type: object properties: id: type: string format: uuid organizationId: type: string format: uuid nullable: true projectId: type: string format: uuid nullable: true createdByUserId: type: string format: uuid nullable: true name: type: string description: type: string nullable: true target: type: string description: URL, host, or synthetic test target being monitored type: type: string enum: - http_request - website - ping_host - port_check - synthetic_test status: type: string enum: - up - down - paused - pending - maintenance - error frequencyMinutes: type: integer description: Check interval in minutes enabled: type: boolean config: anyOf: - $ref: "#/components/schemas/MonitorConfig" - type: "null" alertConfig: anyOf: - $ref: "#/components/schemas/MonitorAlertConfig" - type: "null" lastCheckAt: type: string format: date-time nullable: true lastStatusChangeAt: type: string format: date-time nullable: true mutedUntil: type: string format: date-time nullable: true scheduledJobId: type: string nullable: true recentResults: type: array items: $ref: "#/components/schemas/MonitorResult" createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true MonitorResult: type: object properties: id: type: string format: uuid monitorId: type: string format: uuid checkedAt: type: string format: date-time location: type: string status: type: string enum: - up - down - error - timeout responseTimeMs: type: integer nullable: true description: Response time in milliseconds details: anyOf: - $ref: "#/components/schemas/MonitorResultDetails" - type: "null" isUp: type: boolean isStatusChange: type: boolean consecutiveFailureCount: type: integer consecutiveSuccessCount: type: integer alertsSentForFailure: type: integer alertsSentForRecovery: type: integer testExecutionId: type: string nullable: true testReportS3Url: type: string nullable: true executionGroupId: type: string nullable: true MonitorStats: type: object properties: success: type: boolean data: type: object properties: period24h: type: object properties: totalChecks: type: integer upChecks: type: integer uptimePercentage: type: number nullable: true avgResponseTimeMs: type: integer nullable: true p95ResponseTimeMs: type: integer nullable: true period30d: type: object properties: totalChecks: type: integer upChecks: type: integer uptimePercentage: type: number nullable: true avgResponseTimeMs: type: integer nullable: true p95ResponseTimeMs: type: integer nullable: true meta: type: object properties: monitorId: type: string format: uuid location: type: string calculatedAt: type: string format: date-time source: type: string enum: - aggregates - aggregates+raw_p95 - aggregates+raw - raw Variable: type: object properties: id: type: string format: uuid projectId: type: string format: uuid key: type: string pattern: ^[A-Z][A-Z0-9_]*$ minLength: 4 maxLength: 20 description: Variable key. Uppercase letters, digits, and underscores only; 4-20 characters; must not use the `SUPERCHECK_` prefix or a reserved name (for example PATH, HOME). type: type: string enum: - variable - secret - file description: Variable type. File variables expose metadata in API responses; file contents are not returned. value: type: string description: Plaintext for regular variables, redacted for secrets, and empty for file variables isSecret: type: boolean description: type: string nullable: true fileName: type: string nullable: true fileSize: type: integer nullable: true mimeType: type: string nullable: true createdAt: type: string format: date-time updatedAt: type: string format: date-time nullable: true Tag: type: object properties: id: type: string format: uuid name: type: string color: type: string nullable: true CliToken: type: object properties: id: type: string format: uuid name: type: string start: type: string description: Display prefix (e.g. sck_live_a1b2...) enabled: type: boolean expiresAt: type: string format: date-time nullable: true lastRequest: type: string format: date-time nullable: true createdAt: type: string format: date-time TriggerKey: type: object properties: id: type: string format: uuid name: type: string start: type: string description: Display prefix (e.g. sck_trigger_f1e2...) enabled: type: boolean jobId: type: string format: uuid expiresAt: type: string format: date-time nullable: true lastRequest: type: string format: date-time nullable: true createdByName: type: string nullable: true createdAt: type: string format: date-time NotificationProvider: type: object properties: id: type: string format: uuid name: type: string type: type: string enum: - email - slack - webhook - telegram - discord - teams enabled: type: boolean config: type: object lastUsed: type: string format: date-time nullable: true createdAt: type: string format: date-time AlertEvent: type: object properties: id: type: string format: uuid type: type: string message: type: string severity: type: string enum: - info - warning - critical resourceId: type: string format: uuid resourceType: type: string createdAt: type: string format: date-time AuditEntry: type: object properties: id: type: string format: uuid action: type: string userId: type: string format: uuid userName: type: string details: type: object ipAddress: type: string createdAt: type: string format: date-time Location: type: object properties: id: type: string name: type: string region: type: string JobAlertConfig: type: object properties: enabled: type: boolean notificationProviders: type: array items: type: string format: uuid alertOnFailure: type: boolean alertOnSuccess: type: boolean alertOnTimeout: type: boolean failureThreshold: type: integer minimum: 1 recoveryThreshold: type: integer minimum: 1 customMessage: type: string JobTestRef: type: object properties: id: type: string format: uuid required: - id JobLastRun: type: object properties: id: type: string format: uuid status: type: string enum: - queued - running - passed - failed - error - blocked errorDetails: type: string nullable: true durationMs: type: integer nullable: true startedAt: type: string format: date-time nullable: true completedAt: type: string format: date-time nullable: true JobCreateRequest: type: object properties: name: type: string example: Nightly E2E Suite description: type: string cronSchedule: type: string example: 0 2 * * * tests: type: array items: $ref: "#/components/schemas/JobTestRef" minItems: 1 description: Array of test references to include in this job jobType: type: string enum: - playwright - k6 default: playwright alertConfig: $ref: "#/components/schemas/JobAlertConfig" required: - name - tests JobCreateResponse: type: object properties: success: type: boolean job: type: object properties: id: type: string format: uuid name: type: string description: type: string nullable: true cronSchedule: type: string nullable: true nextRunAt: type: string format: date-time nullable: true scheduledJobId: type: string nullable: true jobType: type: string enum: - playwright - k6 JobUpdateRequest: type: object properties: name: type: string description: type: string cronSchedule: type: string tests: type: array items: $ref: "#/components/schemas/JobTestRef" minItems: 1 alertConfig: $ref: "#/components/schemas/JobAlertConfig" JobUpdateResponse: type: object properties: id: type: string format: uuid name: type: string description: type: string nullable: true cronSchedule: type: string nullable: true nextRunAt: type: string format: date-time nullable: true scheduledJobId: type: string nullable: true testCount: type: integer JobTriggerResponseData: type: object properties: jobId: type: string format: uuid jobName: type: string runId: type: string format: uuid status: type: string enum: - queued - running position: type: integer nullable: true testCount: type: integer triggeredBy: type: string triggeredAt: type: string format: date-time JobTriggerResponse: type: object properties: success: type: boolean message: type: string data: $ref: "#/components/schemas/JobTriggerResponseData" JobTriggerInfoResponse: type: object properties: success: type: boolean job: type: object properties: id: type: string format: uuid name: type: string status: type: string enum: - pending - running - passed - failed - error triggerUrl: type: string documentation: type: object properties: method: type: string headers: type: object additionalProperties: type: string description: type: string example: type: string notes: type: array items: type: string RunStatusResponse: type: object properties: runId: type: string format: uuid jobId: type: string format: uuid nullable: true status: type: string enum: - queued - running - passed - failed - error - blocked startedAt: type: string format: date-time nullable: true completedAt: type: string format: date-time nullable: true durationMs: type: integer nullable: true description: Duration in milliseconds errorDetails: type: string nullable: true reportUrl: type: string nullable: true description: URL to the detailed run report MonitorLocationConfig: type: object properties: enabled: type: boolean locations: type: array items: type: string threshold: type: integer strategy: type: string enum: - all - majority - any MonitorConfig: type: object properties: method: type: string enum: - GET - POST - PUT - DELETE - PATCH - HEAD - OPTIONS headers: type: object additionalProperties: type: string body: type: string expectedStatusCodes: type: string keywordInBody: type: string keywordInBodyShouldBePresent: type: boolean responseBodyJsonPath: type: object properties: path: type: string expectedValue: {} auth: type: object properties: type: type: string enum: - none - basic - bearer username: type: string password: type: string token: type: string port: type: integer protocol: type: string enum: - tcp - udp expectClosed: type: boolean enableSslCheck: type: boolean sslDaysUntilExpirationWarning: type: integer sslCheckFrequencyHours: type: integer sslLastCheckedAt: type: string format: date-time nullable: true sslCheckOnStatusChange: type: boolean checkExpiration: type: boolean daysUntilExpirationWarning: type: integer checkRevocation: type: boolean timeoutSeconds: type: integer minimum: 1 regions: type: array items: type: string locationConfig: $ref: "#/components/schemas/MonitorLocationConfig" retryStrategy: type: object properties: maxRetries: type: integer backoffFactor: type: integer deprecated: true description: Unsupported for monitors. Accepted for compatibility but ignored; it does not change execution retries. Do not set this field in new configurations. alertChannels: type: array items: type: string testId: type: string format: uuid testTitle: type: string playwrightOptions: type: object properties: headless: type: boolean timeout: type: integer retries: type: integer additionalProperties: true MonitorAlertConfig: type: object properties: enabled: type: boolean notificationProviders: type: array items: type: string format: uuid alertOnFailure: type: boolean alertOnRecovery: type: boolean alertOnSslExpiration: type: boolean failureThreshold: type: integer minimum: 1 recoveryThreshold: type: integer minimum: 1 customMessage: type: string MonitorResultDetails: type: object properties: statusCode: type: integer nullable: true statusText: type: string nullable: true errorMessage: type: string nullable: true responseHeaders: type: object additionalProperties: type: string responseBodySnippet: type: string nullable: true ipAddress: type: string nullable: true location: type: string nullable: true sslCertificate: type: object properties: valid: type: boolean issuer: type: string nullable: true subject: type: string nullable: true validFrom: type: string nullable: true validTo: type: string nullable: true daysRemaining: type: integer nullable: true additionalProperties: true MonitorCreateRequest: type: object properties: name: type: string example: API Health Check description: type: string type: type: string enum: - http_request - website - ping_host - port_check - synthetic_test default: http_request target: type: string description: URL, host, or synthetic test target to monitor frequencyMinutes: type: integer description: Check interval in minutes default: 5 minimum: 1 maximum: 1440 example: 5 enabled: type: boolean default: true config: $ref: "#/components/schemas/MonitorConfig" alertConfig: $ref: "#/components/schemas/MonitorAlertConfig" required: - name - type MonitorUpdateRequest: type: object properties: name: type: string description: type: string type: type: string enum: - http_request - website - ping_host - port_check - synthetic_test target: type: string frequencyMinutes: type: integer minimum: 1 maximum: 1440 enabled: type: boolean status: type: string enum: - up - down - paused - pending - maintenance - error config: $ref: "#/components/schemas/MonitorConfig" alertConfig: $ref: "#/components/schemas/MonitorAlertConfig" ValidationScriptRequest: type: object properties: script: type: string description: Test script content to validate testType: type: string enum: - browser - api - performance - database - custom description: Optional expected test type used for script/type compatibility checks required: - script ValidationScriptSuccessResponse: type: object properties: valid: type: boolean const: true message: type: string warnings: type: array items: type: string ValidationScriptErrorResponse: type: object properties: valid: type: boolean const: false error: type: string warnings: type: array items: type: string line: type: integer nullable: true column: type: integer nullable: true errorType: type: string nullable: true isValidationError: type: boolean MonitorNotificationLink: type: object properties: id: type: string format: uuid monitorId: type: string format: uuid notificationProviderId: type: string format: uuid MonitorPermissionsResponse: type: object properties: canView: type: boolean canEdit: type: boolean canDelete: type: boolean canToggle: type: boolean userRole: type: string MonitorLocationStats: type: object properties: location: type: string totalChecks: type: integer nullable: true upChecks: type: integer nullable: true uptimePercentage: type: number nullable: true avgResponseTime: type: number nullable: true minResponseTime: type: number nullable: true maxResponseTime: type: number nullable: true MonitorCollectionUpdateRequest: allOf: - $ref: "#/components/schemas/MonitorUpdateRequest" - type: object required: - id properties: id: type: string format: uuid description: Monitor ID to update OrganizationSummary: type: object properties: id: type: string name: type: string slug: type: string logo: type: string nullable: true createdAt: type: string format: date-time role: type: string enum: - org_owner - org_admin - project_admin - project_editor - project_viewer isActive: type: boolean subscriptionPlan: type: string nullable: true subscriptionStatus: type: string nullable: true subscriptionEndsAt: type: string format: date-time nullable: true OrganizationDetail: type: object properties: id: type: string name: type: string slug: type: string nullable: true logo: type: string nullable: true createdAt: type: string format: date-time metadata: type: object nullable: true role: type: string stats: type: object properties: projectCount: type: integer memberCount: type: integer OrganizationCurrent: type: object properties: id: type: string name: type: string slug: type: string nullable: true logo: type: string nullable: true createdAt: type: string format: date-time OrganizationStats: type: object properties: projects: type: integer jobs: type: integer tests: type: integer monitors: type: integer runs: type: integer members: type: integer OrganizationMember: type: object properties: id: type: string name: type: string email: type: string role: type: string enum: - org_owner - org_admin - project_admin - project_editor - project_viewer joinedAt: type: string format: date-time projects: type: array items: type: object properties: projectId: type: string projectName: type: string OrganizationInvitation: type: object properties: id: type: string email: type: string role: type: string status: type: string expiresAt: type: string format: date-time inviterName: type: string inviterEmail: type: string OrganizationUpdateRequest: type: object required: - name properties: name: type: string minLength: 2 maxLength: 50 description: Display name. Leading and trailing whitespace is trimmed. slug: type: string nullable: true logo: type: string nullable: true metadata: type: object nullable: true OrganizationInviteRequest: type: object required: - email - role properties: email: type: string format: email role: type: string enum: - org_owner - org_admin - project_admin - project_editor - project_viewer selectedProjects: type: array items: type: string description: Required for project_admin and project_editor. Must be active projects in the current organization. OrganizationMemberUpdateRequest: type: object required: - role properties: role: type: string enum: - org_owner - org_admin - project_admin - project_editor - project_viewer selectedProjects: type: array items: type: string projectAssignments: type: array description: Accepted as project ID strings or `{ projectId }` objects. Normalized to selectedProjects. items: oneOf: - type: string - type: object properties: projectId: type: string LocationDisplayMetadata: type: object description: Display-only location metadata. Inactive locations are historical labels, never execution choices. required: - code - name - region - flag - coordinates - isEnabled properties: code: type: string name: type: string region: type: string nullable: true flag: type: string nullable: true coordinates: type: object nullable: true required: - lat - lon properties: lat: type: number lon: type: number isEnabled: type: boolean ErrorResponse: type: object properties: error: type: string details: type: object additionalProperties: true description: Validation details (flattened schema errors) when the request body is rejected. required: - error RequirementTag: type: object properties: id: type: string format: uuid name: type: string color: type: string nullable: true RequirementListItem: type: object description: Requirement as returned by the list endpoint. properties: id: type: string format: uuid title: type: string description: type: string nullable: true priority: type: string enum: - low - medium - high nullable: true tags: type: array items: $ref: "#/components/schemas/RequirementTag" tagNames: type: array items: type: string description: Tag names in stored casing, sorted alphabetically. testIds: type: array items: type: string format: uuid description: IDs of the tests linked to this requirement (limited to tests in the current project). sourceDocumentId: type: string format: uuid nullable: true sourceDocumentName: type: string nullable: true sourceSection: type: string nullable: true externalId: type: string nullable: true externalUrl: type: string nullable: true externalProvider: type: string nullable: true createdBy: type: string nullable: true createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true coverageStatus: type: string enum: - covered - failing - missing description: "`missing` when no coverage has been computed yet." linkedTestCount: type: integer passedTestCount: type: integer failedTestCount: type: integer RequirementCoverage: type: object properties: status: type: string enum: - covered - failing - missing linkedTestCount: type: integer passedTestCount: type: integer failedTestCount: type: integer lastEvaluatedAt: type: string format: date-time nullable: true Requirement: type: object description: Requirement as returned by the detail, create, update and test-link endpoints. properties: id: type: string format: uuid title: type: string description: type: string nullable: true priority: type: string enum: - low - medium - high nullable: true tags: type: array items: type: string description: Tag names. externalId: type: string nullable: true externalUrl: type: string nullable: true testIds: type: array items: type: string format: uuid coverage: allOf: - $ref: "#/components/schemas/RequirementCoverage" nullable: true description: "`null` when no coverage has been computed yet." createdAt: type: string format: date-time nullable: true updatedAt: type: string format: date-time nullable: true RequirementResponse: type: object properties: requirement: $ref: "#/components/schemas/Requirement" RequirementCreateRequest: type: object additionalProperties: false properties: title: type: string minLength: 1 maxLength: 500 example: Users can reset their password description: type: string maxLength: 10000 nullable: true priority: type: string enum: - low - medium - high tags: type: array maxItems: 10 items: type: string minLength: 1 maxLength: 50 description: Tag names. Matched case-insensitively; missing tags are created. Duplicates (ignoring case) are collapsed. On update, replaces the whole tag set. externalId: type: string maxLength: 255 nullable: true externalUrl: type: string maxLength: 2048 nullable: true description: "`http` or `https` URL. An empty string is treated as no URL." testIds: type: array maxItems: 100 items: type: string format: uuid description: Tests to link. Must belong to the current project. On update, replaces the whole set of linked tests. required: - title RequirementUpdateRequest: type: object additionalProperties: false description: Partial update. Omitted fields are preserved; `null` clears `description`, `externalId` and `externalUrl`. properties: title: type: string minLength: 1 maxLength: 500 description: type: string maxLength: 10000 nullable: true priority: type: string enum: - low - medium - high tags: type: array maxItems: 10 items: type: string minLength: 1 maxLength: 50 description: Tag names. Matched case-insensitively; missing tags are created. Duplicates (ignoring case) are collapsed. On update, replaces the whole tag set. externalId: type: string maxLength: 255 nullable: true externalUrl: type: string maxLength: 2048 nullable: true description: "`http` or `https` URL. An empty string is treated as no URL." testIds: type: array maxItems: 100 items: type: string format: uuid description: Tests to link. Must belong to the current project. On update, replaces the whole set of linked tests. RequirementTestIdsRequest: type: object additionalProperties: false properties: testIds: type: array minItems: 1 maxItems: 100 items: type: string format: uuid required: - testIds RequirementLinkedTest: type: object properties: id: type: string format: uuid title: type: string type: type: string description: Test type, or `unknown`. StatusPageUpdateRequest: type: object additionalProperties: false description: Any subset of the fields below; at least one is required. `subdomain` and `customDomainVerified` are managed by the server and rejected with 400. properties: name: type: string minLength: 1 maxLength: 255 headline: type: string maxLength: 255 pageDescription: type: string maxLength: 2000 supportUrl: type: string maxLength: 500 description: "Support contact: an email address or an `http(s)` URL. Empty string clears it." timezone: type: string maxLength: 50 language: type: string pattern: ^[a-z]{2,3}(-[A-Z]{2})?$ description: Public page language (ISO 639-1), for example `en` or `pt-BR`. customDomain: type: string maxLength: 255 description: Hostname for the public page, lower-cased by the server. Empty string removes it. Changing it resets verification (`customDomainVerified` becomes false). It must not use the platform status page domain or its subdomains, must not be used by another status page (409), and requires custom domains to be configured on the deployment (400) and available for your account (403). allowPageSubscribers: type: boolean allowEmailSubscribers: type: boolean allowWebhookSubscribers: type: boolean allowSlackSubscribers: type: boolean allowIncidentSubscribers: type: boolean allowRssFeed: type: boolean cssBodyBackgroundColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssFontColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssLightFontColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssGreens: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssYellows: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssOranges: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssBlues: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssReds: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssBorderColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssGraphColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssLinkColor: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. cssNoData: type: string pattern: ^#[0-9A-Fa-f]{6}$ description: Hex color such as `#1a2b3c`. status: type: string enum: - draft - published - archived description: Lifecycle status. `draft` and `archived` unpublish the page. See the operation description for publish preconditions. StatusPageComponentDto: type: object properties: id: type: string format: uuid name: type: string description: type: string nullable: true position: type: integer monitorIds: type: array items: type: string format: uuid status: type: string enum: - operational - degraded_performance - partial_outage - major_outage - under_maintenance showcase: type: boolean nullable: true onlyShowIfDegraded: type: boolean nullable: true aggregationMethod: type: string enum: - worst_case - best_case - weighted_average - majority_vote failureThreshold: type: integer autoCreateIncidents: type: boolean serviceId: type: string format: uuid nullable: true StatusPageComponentCreateRequest: type: object additionalProperties: false properties: name: type: string minLength: 1 maxLength: 255 description: type: string maxLength: 2000 monitorIds: type: array maxItems: 100 items: type: string format: uuid description: Monitors of the current project to link. Duplicates are collapsed. On update, replaces the whole set. status: type: string enum: - operational - degraded_performance - partial_outage - major_outage - under_maintenance description: Manual status. When omitted while monitors are linked, the status is derived from the monitors. default: operational showcase: type: boolean description: Show the component on the public page. default: true onlyShowIfDegraded: type: boolean default: false position: type: integer minimum: 0 maximum: 1000 default: 0 aggregationMethod: type: string enum: - worst_case - best_case - weighted_average - majority_vote default: worst_case autoCreateIncidents: type: boolean serviceId: type: string format: uuid nullable: true description: AI SRE service in the current project. monitorWeights: type: object additionalProperties: type: integer minimum: 1 maximum: 100 description: Weight per monitor ID (max 100 entries); default weight is 1. failureThreshold: type: integer minimum: 1 maximum: 100 default: 1 required: - name StatusPageComponentUpdateRequest: type: object additionalProperties: false description: Any subset of fields. Omitted fields are preserved. properties: name: type: string minLength: 1 maxLength: 255 description: type: string maxLength: 2000 nullable: true monitorIds: type: array maxItems: 100 items: type: string format: uuid description: Monitors of the current project to link. Duplicates are collapsed. On update, replaces the whole set. status: type: string enum: - operational - degraded_performance - partial_outage - major_outage - under_maintenance description: Manual status. When omitted while monitors are linked, the status is derived from the monitors. showcase: type: boolean description: Show the component on the public page. onlyShowIfDegraded: type: boolean position: type: integer minimum: 0 maximum: 1000 aggregationMethod: type: string enum: - worst_case - best_case - weighted_average - majority_vote autoCreateIncidents: type: boolean serviceId: type: string format: uuid nullable: true description: AI SRE service in the current project. monitorWeights: type: object additionalProperties: type: integer minimum: 1 maximum: 100 description: Weight per monitor ID (max 100 entries); default weight is 1. failureThreshold: type: integer minimum: 1 maximum: 100