{
  "openapi": "3.1.0",
  "info": {
    "title": "XXC Watcher API",
    "version": "1.0.0",
    "description": "Private-by-default website monitoring. Bearer token scopes plus account RBAC. UTC timestamps. JSON errors contain error.code, error.message and error.request_id."
  },
  "servers": [
    {
      "url": "https://watch.xxc.dk/api/v1"
    }
  ],
  "paths": {
    "/targets": {
      "get": {
        "summary": "List authorized targets",
        "description": "Required scope: targets:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "group",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ]
      },
      "post": {
        "summary": "Create target and queue initial checks",
        "description": "Required scope: targets:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TargetInput"
              }
            }
          }
        }
      }
    },
    "/targets/{id}": {
      "get": {
        "summary": "Retrieve target and rules",
        "description": "Required scope: targets:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      },
      "patch": {
        "summary": "Update target and rules",
        "description": "Required scope: targets:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TargetInput"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete target and history",
        "description": "Required scope: targets:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/targets/{id}/check": {
      "post": {
        "summary": "Queue immediate check",
        "description": "Required scope: targets:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/targets/{id}/history": {
      "get": {
        "summary": "Read check history",
        "description": "Required scope: targets:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/targets/{id}/changes": {
      "get": {
        "summary": "Read content changes",
        "description": "Required scope: targets:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/targets/{id}/screenshots": {
      "get": {
        "summary": "Read screenshot metadata",
        "description": "Required scope: targets:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/workers": {
      "get": {
        "summary": "Actual worker state",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/workers/{id}": {
      "get": {
        "summary": "Worker details and history",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/queues": {
      "get": {
        "summary": "SQL and Beanstalkd queue statistics",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/jobs": {
      "get": {
        "summary": "List durable jobs",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/jobs/{id}": {
      "get": {
        "summary": "Read job and attempts",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/dashboard": {
      "get": {
        "summary": "Dashboard metrics (admin)",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/events": {
      "get": {
        "summary": "Worker events after cursor",
        "description": "Required scope: operations:read. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/admin/workers/scale": {
      "post": {
        "summary": "Set desired worker count, 0\u2013200",
        "description": "Required scope: admin:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "count"
                ],
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 200
                  }
                }
              }
            }
          }
        }
      }
    },
    "/admin/jobs/{id}/retry": {
      "post": {
        "summary": "Retry failed job",
        "description": "Required scope: admin:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/admin/jobs/{id}/release": {
      "post": {
        "summary": "Release delayed job",
        "description": "Required scope: admin:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/admin/jobs/{id}/cancel": {
      "post": {
        "summary": "Cancel pending job; confirm=true required",
        "description": "Required scope: admin:write. Server-side RBAC and ownership also apply.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful JSON response"
          },
          "201": {
            "description": "Target created"
          },
          "202": {
            "description": "Job or desired state accepted"
          },
          "400": {
            "description": "Malformed request"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Permission or scope denied"
          },
          "404": {
            "description": "Resource not found"
          },
          "409": {
            "description": "Idempotency conflict"
          },
          "422": {
            "description": "Validation failed"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "confirm"
                ],
                "properties": {
                  "confirm": {
                    "type": "boolean",
                    "const": true
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "TargetInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 190
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "notes": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "paused": {
            "type": "boolean"
          },
          "public": {
            "type": "boolean",
            "default": false
          },
          "screenshot_enabled": {
            "type": "boolean"
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Rule"
            }
          }
        }
      },
      "Rule": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "interval_seconds": {
            "type": "integer",
            "minimum": 60
          },
          "config": {
            "type": "object"
          },
          "enabled": {
            "type": "boolean"
          },
          "baseline_strategy": {
            "enum": [
              "rolling",
              "fixed"
            ]
          }
        }
      }
    }
  }
}