# Planekeeper API Schemas # This file contains all schema definitions for the OpenAPI specification ErrorResponse: type: object required: - error properties: error: type: string description: Error message example: invalid request body message: type: string description: Additional error details example: too many requests, please try again later HealthResponse: type: object required: - status properties: status: type: string enum: [healthy, unhealthy] example: healthy version: $ref: "#/VersionData" error: type: string description: Error message when unhealthy VersionData: type: object properties: version: type: string example: 0.1.0-alpha.20260101T000000 commit: type: string example: abc123 build_date: type: string example: "2026-01-01T00:00:00Z" go_version: type: string example: go1.25.5 HeartbeatResponse: x-go-name: HeartbeatResponsePayload # Avoids enum clash type: object required: - status - instance_id - organization_id properties: status: type: string enum: [ok] example: ok instance_id: type: string format: uuid example: 550e8400-e29b-41d4-a716-446655440000 organization_id: type: integer format: int64 description: Organization ID associated with the API key (derived from authentication) example: 1 agent_config: $ref: "#/AgentConfig" AgentConfig: type: object description: Dynamic configuration for agents, returned with heartbeat properties: poll_interval_seconds: type: integer description: Polling interval in seconds example: 30 rate_limit_max_requests: type: integer description: Maximum API requests per rate limit window example: 100 rate_limit_window_seconds: type: integer description: Rate limit window duration in seconds example: 60 rate_limit_skip_failed: type: boolean description: Whether to skip failed requests in rate limit counting example: false HeartbeatRequest: type: object description: Optional metadata sent with heartbeat properties: capabilities: type: array description: List of job types the agent can handle items: $ref: "#/JobType" example: ["gather", "scrape"] available_credentials: type: array description: Names of git credentials configured on this agent items: type: string example: ["github-private", "gitlab-token"] hostname: type: string description: Agent's hostname example: agent-node-01 ip_address: type: string description: Agent's self-reported IP address example: "192.168.1.100" version: type: string description: Agent build version example: "1.2.0" gather_source_types: type: array description: Gather source types the agent supports items: type: string example: ["github_releases", "helm_repository"] scrape_parse_types: type: array description: Scrape parse types the agent supports items: type: string example: ["yq", "jq", "regex"] credential_types: type: object additionalProperties: type: string description: Map of credential name to credential type example: {"github-private": "https_pat", "deploy-key": "ssh_key"} SourceType: type: string enum: - github_releases - helm_repository - oci_registry description: Type of upstream source for release gathering example: github_releases GatherSourceConfig: type: object description: | Source-specific configuration for gather jobs. Properties vary by source_type. Common properties apply to all source types. Source-specific properties are documented under their respective sections. properties: # Common properties (all source types) tag_filter: type: string description: | Regex pattern to filter which tags/versions are gathered. Only releases matching this pattern will be collected. example: "^v[0-9]" version_regex: type: string description: | Regex with capture group to extract semantic version from tag. The first capture group (parentheses) will be used as the version. If not specified, defaults to stripping 'v' prefix. example: "v(.*)" # GitHub-specific properties (source_type: github_releases) max_pages: type: integer minimum: 1 maximum: 100 default: 10 description: | [GitHub only] Maximum number of API pages to fetch. Each page contains up to per_page releases. example: 10 per_page: type: integer minimum: 1 maximum: 100 default: 100 description: | [GitHub only] Number of releases per API page. example: 100 include_drafts: type: boolean default: false description: | [GitHub only] Whether to include draft releases. By default, draft releases are excluded. example: false # Helm-specific properties (source_type: helm_repository) max_versions: type: integer minimum: 1 maximum: 10000 default: 1000 description: | [Helm only] Maximum number of chart versions to process. Helm repositories can have thousands of versions. example: 1000 # OCI-specific properties (source_type: oci_registry) max_tags: type: integer minimum: 1 maximum: 10000 default: 100 description: | [OCI only] Maximum number of image tags to process. example: 100 fetch_dates: type: boolean default: true description: | [OCI only] Whether to fetch manifest dates for each tag. Disabling this improves performance but release dates will be zero. example: true insecure: type: boolean default: false description: | [OCI only] Use HTTP instead of HTTPS for registry communication. Only use for local development registries. example: false additionalProperties: false ParseType: type: string enum: - yq - jq - regex - manual description: Type of parser for version extraction. Use 'manual' for manual version entry (no agent required). example: yq VersionTransform: type: string enum: - none - add_v_lower - add_v_upper - strip_v_lower - strip_v_upper description: | Transformation to apply to extracted version string: - none: No transformation (default) - add_v_lower: Add lowercase "v" prefix (1.0.0 -> v1.0.0) - add_v_upper: Add uppercase "V" prefix (1.0.0 -> V1.0.0) - strip_v_lower: Remove lowercase "v" prefix (v1.0.0 -> 1.0.0) - strip_v_upper: Remove uppercase "V" prefix (V1.0.0 -> 1.0.0) default: none example: strip_v_lower JobType: type: string enum: - gather - scrape - helm_sync description: Type of job example: gather JobStatus: type: string enum: - pending - queued - in_progress - completed - failed description: Current status of the job example: pending GatherJob: type: object required: - id - artifact_name - source_type - status properties: id: type: integer format: int64 example: 123 organization_id: type: integer format: int64 nullable: true description: Organization ID (null for global jobs) example: 1 name: type: string description: Human-readable name for this gather job example: Argo Workflows Helm Chart artifact_name: type: string description: Name of the artifact (e.g., owner/repo for GitHub) example: kubernetes/kubernetes source_type: $ref: "#/SourceType" status: $ref: "#/JobStatus" schedule: type: string description: Cron schedule for recurring jobs example: "0 0 * * *" error_message: type: string description: Error message if job failed attempts: type: integer format: int32 description: Number of attempts made example: 1 max_attempts: type: integer format: int32 description: Maximum number of retry attempts example: 3 claimed_by: type: string format: uuid description: UUID of the agent that claimed the job claimed_at: type: string format: date-time description: When the job was claimed next_run_at: type: string format: date-time description: When the job should next run created_at: type: string format: date-time updated_at: type: string format: date-time completed_at: type: string format: date-time source_config: $ref: "#/GatherSourceConfig" credential_name: type: string description: Name of registry credential required (configured on agent) example: dockerhub is_global: type: boolean description: Whether releases from this job are visible to all organizations example: false parent_sync_job_id: type: integer format: int64 nullable: true description: ID of the helm sync job that created this gather job labels: type: object additionalProperties: true description: Key-value labels for categorization and filtering example: {"category": "container-runtime", "tier": "infrastructure"} suggest_global: type: boolean description: Whether this job has been suggested for the global pool example: false has_global_equivalent: type: boolean description: Whether a global job with the same artifact_name and source_type already exists example: false recent_runs: type: array items: type: string description: Status strings of the last 5 task executions (newest first) example: ["completed", "completed", "failed", "completed", "completed"] ScrapeJob: type: object required: - id - organization_id - repository_url - ref - target_file - parse_type - parse_expression - status properties: id: type: integer format: int64 example: 123 organization_id: type: integer format: int64 example: 1 name: type: string description: Human-readable name for this scrape job (optional, for easier identification) example: Nginx Ingress Chart Version repository_url: type: string description: URL of the Git repository to scrape example: https://github.com/helm/charts ref: type: string description: Git ref (branch, tag, or commit) to scrape example: main target_file: type: string description: Path to the file containing version information example: stable/nginx-ingress/Chart.yaml parse_type: $ref: "#/ParseType" parse_expression: type: string description: Expression used to extract version (yq/jq path or regex) example: ".version" status: $ref: "#/JobStatus" schedule: type: string description: Cron schedule for recurring jobs example: "0 0 * * *" error_message: type: string description: Error message if job failed attempts: type: integer format: int32 description: Number of attempts made example: 1 max_attempts: type: integer format: int32 description: Maximum number of retry attempts example: 3 claimed_by: type: string format: uuid description: UUID of the agent that claimed the job claimed_at: type: string format: date-time description: When the job was claimed next_run_at: type: string format: date-time description: When the job should next run created_at: type: string format: date-time updated_at: type: string format: date-time completed_at: type: string format: date-time history_limit: type: integer format: int32 description: Number of version snapshots to keep (1-20, null uses global default) example: 5 credential_name: type: string description: Name of git credential required (configured on agent) example: github-private version_transform: $ref: "#/VersionTransform" owner_user_id: type: integer format: int64 description: User ID of the scrape job owner (nullable) nullable: true owner_name: type: string description: Display name of the owner (joined from users table) recent_runs: type: array items: type: string description: Status strings of the last 5 task executions (newest first) example: ["completed", "completed", "failed", "completed", "completed"] CreateGatherJobRequest: type: object required: - artifact_name - source_type properties: name: type: string description: Human-readable name for this gather job (optional, for easier identification) example: Argo Workflows Helm Chart artifact_name: type: string description: | Name of the artifact to gather releases for. Format depends on source_type: - github_releases: owner/repo (e.g., kubernetes/kubernetes) - helm_repository: repo-host/repo-path/chart-name (e.g., argoproj.github.io/argo-helm/argo-cd) - oci_registry: registry/namespace/image (e.g., docker.io/library/nginx, ghcr.io/owner/image) example: kubernetes/kubernetes source_type: $ref: "#/SourceType" schedule: type: string description: Optional cron schedule for recurring jobs example: "0 0 * * 0" source_config: $ref: "#/GatherSourceConfig" credential_name: type: string description: Name of registry credential required (configured on agent, used for oci_registry source type) example: dockerhub is_global: type: boolean description: Whether releases from this job should be visible to all organizations (internal use, requires admin) default: false labels: type: object additionalProperties: true description: Key-value labels for categorization and filtering example: {"category": "container-runtime"} suggest_global: type: boolean description: Suggest this job for inclusion in the global pool. If approved by an admin, a copy will be added to the global catalog. default: false CreateScrapeJobRequest: type: object required: - parse_type properties: name: type: string description: Human-readable name for this scrape job (optional, for easier identification) example: Nginx Ingress Chart Version repository_url: type: string description: URL of the Git repository to scrape example: https://github.com/helm/charts ref: type: string description: Git ref to scrape (default is 'main') example: main default: main target_file: type: string description: Path to the file containing version information example: stable/nginx-ingress/Chart.yaml parse_type: $ref: "#/ParseType" parse_expression: type: string description: Expression used to extract version example: ".version" schedule: type: string description: Optional cron schedule for recurring jobs example: "0 0 * * *" history_limit: type: integer format: int32 minimum: 1 maximum: 20 description: Number of version snapshots to keep (1-20, optional, uses global default if not specified) example: 5 credential_name: type: string description: Name of git credential to use (must exist on agent) example: github-private version_transform: $ref: "#/VersionTransform" owner_user_id: type: integer format: int64 description: User ID of the scrape job owner (optional) nullable: true SetManualVersionRequest: type: object required: - version properties: version: type: string description: The version string to record for this manual scrape job example: "1.2.3" ListGatherJobsResponse: x-go-name: ListGatherJobsResponsePayload # Avoids enum clash type: object required: - jobs - limit - offset properties: jobs: type: array items: $ref: "#/GatherJob" total_count: type: integer format: int32 description: Total number of items matching the query (for pagination) example: 100 limit: type: integer format: int32 example: 50 offset: type: integer format: int32 example: 0 ListScrapeJobsResponse: x-go-name: ListScrapeJobsResponsePayload # Avoids enum clash type: object required: - jobs - limit - offset properties: jobs: type: array items: $ref: "#/ScrapeJob" total_count: type: integer format: int32 description: Total number of items matching the query (for pagination) example: 100 limit: type: integer format: int32 example: 50 offset: type: integer format: int32 example: 0 HelmSyncJob: type: object required: - id - repository_url - status properties: id: type: integer format: int64 example: 123 organization_id: type: integer format: int64 nullable: true description: Organization ID (null for global jobs) example: 1 name: type: string description: Human-readable name for this sync job example: Argo Helm Charts Sync repository_url: type: string description: Helm repository URL to sync charts from example: argoproj.github.io/argo-helm chart_filter: type: string description: Regex pattern to filter which charts to sync example: "^argo-" default_schedule: type: string description: Default cron schedule for created gather jobs example: "0 0 * * *" default_tag_filter: type: string description: Default tag filter for created gather jobs default_version_regex: type: string description: Default version regex for created gather jobs auto_delete_orphans: type: boolean description: Whether to delete gather jobs for charts no longer in repo default: false is_global: type: boolean description: Whether created gather jobs should be global default: false status: $ref: "#/JobStatus" schedule: type: string description: Cron schedule for recurring syncs example: "0 0 * * 0" error_message: type: string description: Error message if job failed attempts: type: integer format: int32 description: Number of attempts made example: 1 max_attempts: type: integer format: int32 description: Maximum number of retry attempts example: 3 claimed_by: type: string format: uuid description: UUID of the agent that claimed the job claimed_at: type: string format: date-time description: When the job was claimed next_run_at: type: string format: date-time description: When the job should next run created_at: type: string format: date-time updated_at: type: string format: date-time completed_at: type: string format: date-time child_job_count: type: integer format: int32 description: Number of gather jobs created by this sync job example: 5 labels: type: object additionalProperties: true description: Key-value labels for categorization and filtering example: {"category": "helm-charts", "provider": "bitnami"} suggest_global: type: boolean description: Whether this job has been suggested for the global pool example: false CreateHelmSyncJobRequest: type: object required: - repository_url properties: name: type: string description: Human-readable name for this sync job example: Argo Helm Charts Sync repository_url: type: string description: Helm repository URL to sync charts from (without https://) example: argoproj.github.io/argo-helm chart_filter: type: string description: Regex pattern to filter which charts to sync example: "^argo-" default_schedule: type: string description: Default cron schedule for created gather jobs example: "0 0 * * *" default_tag_filter: type: string description: Default tag filter for created gather jobs default_version_regex: type: string description: Default version regex for created gather jobs auto_delete_orphans: type: boolean description: Whether to delete gather jobs for charts no longer in repo default: false is_global: type: boolean description: Whether created gather jobs should be global default: false schedule: type: string description: Cron schedule for recurring syncs example: "0 0 * * 0" labels: type: object additionalProperties: true description: Key-value labels for categorization and filtering example: {"category": "helm-charts"} suggest_global: type: boolean description: Suggest this job for inclusion in the global pool. If approved by an admin, a copy will be added to the global catalog. default: false UpdateHelmSyncJobRequest: type: object properties: name: type: string description: Human-readable name for this sync job nullable: true repository_url: type: string description: Helm repository URL to sync charts from chart_filter: type: string description: Regex pattern to filter which charts to sync nullable: true default_schedule: type: string description: Default cron schedule for created gather jobs nullable: true default_tag_filter: type: string description: Default tag filter for created gather jobs nullable: true default_version_regex: type: string description: Default version regex for created gather jobs nullable: true auto_delete_orphans: type: boolean description: Whether to delete gather jobs for charts no longer in repo is_global: type: boolean description: Whether created gather jobs should be global schedule: type: string description: Cron schedule for recurring syncs nullable: true suggest_global: type: boolean description: Suggest this job for inclusion in the global pool nullable: true ListHelmSyncJobsResponse: x-go-name: ListHelmSyncJobsResponsePayload type: object required: - jobs - limit - offset properties: jobs: type: array items: $ref: "#/HelmSyncJob" total_count: type: integer format: int32 description: Total number of items matching the query (for pagination) example: 100 limit: type: integer format: int32 example: 50 offset: type: integer format: int32 example: 0 PendingContribution: type: object required: - id - type - name - source_type - organization_id - created_at properties: id: type: integer format: int64 description: ID of the suggested job type: type: string enum: [gather, helm_sync] description: Type of job being suggested name: type: string description: Human-readable name of the job artifact_name: type: string description: Artifact name (for gather jobs) repository_url: type: string description: Repository URL (for helm sync jobs) source_type: type: string description: Source type (for gather jobs) or "helm_repository" (for helm sync) organization_id: type: integer format: int64 description: Organization that suggested the job organization_name: type: string description: Name of the organization that suggested the job created_at: type: string format: date-time description: When the job was created PendingContributionsList: type: object required: - items - total properties: items: type: array items: $ref: "#/PendingContribution" total: type: integer format: int32 description: Total number of pending contributions PendingContributionsCount: type: object required: - gather_count - helm_sync_count - total properties: gather_count: type: integer format: int32 description: Number of pending gather job suggestions helm_sync_count: type: integer format: int32 description: Number of pending helm sync job suggestions total: type: integer format: int32 description: Total pending suggestions HelmChartInfo: type: object description: Information about a chart discovered in a Helm repository required: - name properties: name: type: string description: Chart name example: argo-cd description: type: string description: Chart description example: A Helm chart for Argo CD latest_version: type: string description: Latest version of the chart example: "5.46.0" HelmSyncChildJobsResponse: type: object required: - jobs properties: jobs: type: array items: $ref: "#/GatherJob" Release: type: object required: - version - tag_name - release_url - release_date - is_prerelease properties: version: type: string description: Semantic version string example: "1.30.0" tag_name: type: string description: Git tag name example: v1.30.0 release_url: type: string format: uri description: URL to the release page example: https://github.com/kubernetes/kubernetes/releases/tag/v1.30.0 release_date: type: string format: date-time description: When the release was published is_prerelease: type: boolean description: Whether this is a pre-release version example: false UpstreamRelease: type: object required: - id - organization_id - job_id - artifact_name - version properties: id: type: integer format: int64 example: 456 organization_id: type: integer format: int64 example: 1 job_id: type: integer format: int64 example: 123 artifact_name: type: string example: kubernetes/kubernetes version: type: string example: "1.30.0" tag_name: type: string example: v1.30.0 release_date: type: string format: date-time release_url: type: string format: uri example: https://github.com/kubernetes/kubernetes/releases/tag/v1.30.0 is_prerelease: type: boolean example: false metadata: type: object additionalProperties: true description: Source-specific metadata (varies by source type) created_at: type: string format: date-time updated_at: type: string format: date-time VersionSnapshot: type: object required: - id - organization_id - job_id - repository_url - target_file - version properties: id: type: integer format: int64 example: 789 organization_id: type: integer format: int64 example: 1 job_id: type: integer format: int64 example: 123 repository_url: type: string example: https://github.com/helm/charts ref: type: string example: main target_file: type: string example: stable/nginx-ingress/Chart.yaml version: type: string example: "1.41.3" raw_content: type: string description: The raw extracted content before parsing metadata: type: object additionalProperties: true description: Additional metadata from the scrape discovered_at: type: string format: date-time created_at: type: string format: date-time ListReleasesResponse: x-go-name: ListReleasesResponsePayload # Avoids enum clash type: object required: - releases - limit - offset properties: releases: type: array items: $ref: "#/UpstreamRelease" total_count: type: integer format: int32 description: Total number of items matching the query (for pagination) example: 100 limit: type: integer format: int32 example: 50 offset: type: integer format: int32 example: 0 ReleasesSummary: type: object required: - total_count - unique_artifacts - stable_count - prerelease_count - artifact_names properties: total_count: type: integer format: int64 description: Total number of releases example: 142 unique_artifacts: type: integer format: int64 description: Number of unique artifact names example: 8 stable_count: type: integer format: int64 description: Number of stable (non-prerelease) releases example: 120 prerelease_count: type: integer format: int64 description: Number of prerelease versions example: 22 latest_release_date: type: string format: date-time description: Date of the most recent release artifact_names: type: array items: type: string description: List of unique artifact names for autocomplete example: ["kubernetes/kubernetes", "helm/helm"] GatherJobsSummary: type: object required: - total_count - pending_count - queued_count - in_progress_count - completed_count - failed_count properties: total_count: type: integer format: int64 description: Total number of gather jobs example: 173 pending_count: type: integer format: int64 description: Number of pending gather jobs example: 10 queued_count: type: integer format: int64 description: Number of queued gather jobs example: 5 in_progress_count: type: integer format: int64 description: Number of in-progress gather jobs example: 2 completed_count: type: integer format: int64 description: Number of completed gather jobs example: 150 failed_count: type: integer format: int64 description: Number of failed gather jobs example: 6 ScrapeJobsSummary: type: object required: - total_count - scheduled_count - with_versions_count properties: total_count: type: integer format: int64 description: Total number of scrape jobs example: 25 scheduled_count: type: integer format: int64 description: Number of scrape jobs with a schedule example: 20 with_versions_count: type: integer format: int64 description: Number of scrape jobs that have at least one version snapshot example: 18 ListVersionSnapshotsResponse: x-go-name: ListVersionSnapshotsResponsePayload # Avoids enum clash type: object required: - versions - limit - offset properties: versions: type: array items: $ref: "#/VersionSnapshot" total_count: type: integer format: int32 description: Total number of items matching the query (for pagination) example: 100 limit: type: integer format: int32 example: 50 offset: type: integer format: int32 example: 0 VersionHistoryResponse: type: object required: - versions - total - effective_limit properties: versions: type: array items: $ref: "#/VersionSnapshot" total: type: integer format: int64 description: Total number of version snapshots for this job example: 15 effective_limit: type: integer format: int32 description: The effective history limit (job-specific or global default) example: 5 TriggerJobResponse: type: object required: - message properties: message: type: string description: Status message example: Job triggered successfully ValidateRegexRequest: type: object required: - pattern properties: pattern: type: string description: The regex pattern to validate example: "version:\\s*([\\d.]+)" ValidateRegexResponse: x-go-name: ValidateRegexResponsePayload # Avoids enum clash type: object required: - valid properties: valid: type: boolean description: Whether the regex pattern is valid example: true error: type: string description: Error message if the pattern is invalid Setting: type: object required: - key - value properties: key: type: string description: The setting key example: version_history_limit value: type: string description: The setting value example: "5" description: type: string description: Description of what the setting controls example: Default number of version snapshots to keep created_at: type: string format: date-time updated_at: type: string format: date-time ListSettingsResponse: x-go-name: ListSettingsResponsePayload # Avoids enum clash type: object required: - settings properties: settings: type: array items: $ref: "#/Setting" ListEffectiveSettingsResponse: x-go-name: ListEffectiveSettingsResponsePayload type: object required: - settings properties: settings: type: array items: $ref: "#/CombinedSetting" CombinedSetting: type: object description: A setting showing both global default and organization override values required: - key - global_value properties: key: type: string description: The setting key example: agent_poll_interval_seconds description: type: string description: Description of what the setting controls example: Default polling interval for agents in seconds global_value: type: string description: The global default value example: "30" org_value: type: string description: The organization-specific override value (absent if using global default) example: "60" ListAgentsResponse: x-go-name: ListAgentsResponsePayload type: object required: - agents properties: agents: type: array items: $ref: "#/AgentInfo" AgentInfo: type: object required: - uuid - organization_id - is_healthy properties: uuid: type: string format: uuid description: Agent's unique identifier example: 550e8400-e29b-41d4-a716-446655440000 organization_id: type: integer format: int64 example: 1 last_heartbeat: type: string format: date-time description: When the agent last reported is_healthy: type: boolean description: Whether the agent is currently healthy capabilities: type: array description: Job types the agent can handle items: type: string example: ["gather", "scrape"] available_credentials: type: array description: Names of git credentials configured on this agent items: type: string example: ["github-private", "gitlab-token"] hostname: type: string description: Agent's hostname ip_address: type: string description: Agent's self-reported IP address remote_address: type: string description: Server-observed IP address version: type: string description: Agent software version build_date: type: string description: Agent build date gather_source_types: type: array description: Gather source types the agent supports items: type: string example: ["github_releases", "helm_repository"] scrape_parse_types: type: array description: Scrape parse types the agent supports items: type: string example: ["yq", "jq", "regex"] credential_types: type: object additionalProperties: type: string description: Map of credential name to credential type example: {"github-private": "https_pat"} metadata: type: object additionalProperties: true description: Additional agent metadata UpdateSettingRequest: type: object required: - value properties: value: type: string description: The new value for the setting example: "10" UpdateGatherJobRequest: type: object properties: name: type: string description: Human-readable name for this gather job (null to clear) example: Argo Workflows Helm Chart nullable: true artifact_name: type: string description: | Name of the artifact to gather releases for. Format depends on source_type: - github_releases: owner/repo (e.g., kubernetes/kubernetes) - helm_repository: repo-host/repo-path/chart-name (e.g., argoproj.github.io/argo-helm/argo-cd) - oci_registry: registry/namespace/image (e.g., docker.io/library/nginx, ghcr.io/owner/image) example: kubernetes/kubernetes source_type: $ref: "#/SourceType" schedule: type: string description: Optional cron schedule for recurring jobs (null to clear) example: "0 0 * * 0" nullable: true source_config: $ref: "#/GatherSourceConfig" credential_name: type: string nullable: true description: Name of registry credential required (configured on agent, null to clear) example: dockerhub is_global: type: boolean description: Whether releases from this job should be visible to all organizations (internal use, requires admin) nullable: true suggest_global: type: boolean description: Suggest this job for inclusion in the global pool nullable: true UpdateScrapeJobRequest: type: object properties: name: type: string description: Human-readable name for this scrape job (optional) example: Nginx Ingress Chart Version repository_url: type: string description: URL of the Git repository to scrape example: https://github.com/helm/charts ref: type: string description: Git ref to scrape example: main target_file: type: string description: Path to the file containing version information example: stable/nginx-ingress/Chart.yaml parse_type: $ref: "#/ParseType" parse_expression: type: string description: Expression used to extract version example: ".version" schedule: type: string description: Optional cron schedule for recurring jobs (null to clear) example: "0 0 * * *" nullable: true history_limit: type: integer format: int32 minimum: 1 maximum: 20 description: Number of version snapshots to keep (1-20, null to use global default) example: 5 nullable: true credential_name: type: string description: Name of git credential to use (must exist on agent, null to clear) example: github-private nullable: true version_transform: $ref: "#/VersionTransform" owner_user_id: type: integer format: int64 description: User ID of the scrape job owner (null to clear) nullable: true PollTaskRequest: type: object required: - capabilities properties: capabilities: type: array description: List of job types the agent can handle items: $ref: "#/JobType" example: ["gather", "scrape"] available_credentials: type: array description: Names of git credentials configured on this agent items: type: string example: ["github-private", "gitlab-token"] TaskAssignment: type: object required: - execution_token - expires_at - job_type - job_id - task_data properties: execution_token: type: string format: uuid description: Unique token for this execution (used for result submission) example: 550e8400-e29b-41d4-a716-446655440000 expires_at: type: string format: date-time description: When this execution token expires job_type: $ref: "#/JobType" job_id: type: integer format: int64 description: The ID of the job being executed example: 123 task_data: $ref: "#/TaskData" TaskData: type: object description: Job-specific data needed to execute the task properties: gather_task: $ref: "#/GatherTaskData" scrape_task: $ref: "#/ScrapeTaskData" helm_sync_task: $ref: "#/HelmSyncTaskData" GatherTaskData: type: object required: - artifact_name - source_type properties: organization_id: type: integer format: int64 nullable: true description: Organization ID (null for global jobs) example: 1 artifact_name: type: string description: | Name of the artifact to gather releases for. Format depends on source_type: - github_releases: owner/repo (e.g., kubernetes/kubernetes) - helm_repository: repo-host/repo-path/chart-name (e.g., argoproj.github.io/argo-helm/argo-cd) - oci_registry: registry/namespace/image (e.g., docker.io/library/nginx, ghcr.io/owner/image) example: kubernetes/kubernetes source_type: $ref: "#/SourceType" source_config: $ref: "#/GatherSourceConfig" credential_name: type: string description: Name of registry credential required (configured on agent) example: dockerhub incremental_since: type: string description: ISO 8601 timestamp for incremental sync (only fetch releases after this date) example: "2026-01-15T00:00:00Z" ScrapeTaskData: type: object required: - organization_id - repository_url - ref - target_file - parse_type - parse_expression properties: organization_id: type: integer format: int64 example: 1 repository_url: type: string description: URL of the Git repository to scrape example: https://github.com/helm/charts ref: type: string description: Git ref (branch, tag, or commit) to scrape example: main target_file: type: string description: Path to the file containing version information example: stable/nginx-ingress/Chart.yaml parse_type: $ref: "#/ParseType" parse_expression: type: string description: Expression used to extract version example: ".version" credential_name: type: string description: Credential name the agent should use example: github-private version_transform: $ref: "#/VersionTransform" HelmSyncTaskData: type: object required: - repository_url properties: organization_id: type: integer format: int64 nullable: true description: Organization ID (null for global jobs) example: 1 repository_url: type: string description: Helm repository URL (e.g., argoproj.github.io/argo-helm) example: argoproj.github.io/argo-helm chart_filter: type: string description: Optional regex pattern to filter which charts to sync example: "^argo-" default_schedule: type: string description: Default cron schedule to apply to created gather jobs example: "0 0 * * *" default_tag_filter: type: string description: Default tag filter to apply to created gather jobs default_version_regex: type: string description: Default version regex to apply to created gather jobs CompleteTaskRequest: x-go-name: CompleteTaskRequestPayload # Avoids enum clash type: object required: - execution_token - success properties: execution_token: type: string format: uuid description: The execution token received from polling example: 550e8400-e29b-41d4-a716-446655440000 success: type: boolean description: Whether the task completed successfully error: type: string description: Error message if the task failed result_data: type: object additionalProperties: true description: Task-specific result data (GatherResultData or ScrapeResultData) CompleteTaskResponse: x-go-name: CompleteTaskResponsePayload # Avoids enum clash type: object required: - status properties: status: type: string enum: - accepted - conflict - error description: Status of the submission example: accepted message: type: string description: Additional status message example: Results accepted for processing LogFailureRequest: type: object required: - execution_token - error_message properties: execution_token: type: string format: uuid description: The execution token for the failed submission example: 550e8400-e29b-41d4-a716-446655440000 error_message: type: string description: Description of the failure example: "connection refused" attempt_number: type: integer description: Which attempt number this failure is for example: 2 RuleType: type: string enum: - days_behind - majors_behind - minors_behind description: Type of monitoring rule example: days_behind AlertSeverity: type: string enum: - moderate - high - critical description: Severity level of an alert (moderate, high, critical) example: moderate RuleParams: type: object description: Parameters for a monitoring rule (varies by rule type) properties: max_days: type: integer description: Maximum days behind for days_behind rule minimum: 1 example: 30 max_majors: type: integer description: Maximum major versions behind for majors_behind rule minimum: 0 example: 1 max_minors: type: integer description: Maximum minor versions behind for minors_behind rule minimum: 0 example: 3 stable_only: type: boolean description: Only consider stable releases (non-prerelease) default: true MonitoringRule: type: object required: - id - name - rule_type - moderate_threshold - high_threshold - critical_threshold - is_active properties: id: type: integer format: int64 example: 123 organization_id: type: integer format: int64 nullable: true description: Organization ID, null for global rules example: 1 name: type: string description: Name of the monitoring rule example: "Kubernetes version staleness" description: type: string description: Description of what this rule monitors rule_type: $ref: "#/RuleType" moderate_threshold: type: integer description: Threshold at which to generate a moderate-level alert example: 30 high_threshold: type: integer description: Threshold at which to generate a high-level alert example: 60 critical_threshold: type: integer description: Threshold at which to generate a critical-level alert example: 90 stable_only: type: boolean description: Only consider stable releases (non-prerelease) default: true is_active: type: boolean description: Whether the rule is active example: true created_at: type: string format: date-time updated_at: type: string format: date-time CreateMonitoringRuleRequest: type: object required: - name - rule_type - moderate_threshold - high_threshold - critical_threshold properties: name: type: string description: Name of the monitoring rule example: "Kubernetes version staleness" description: type: string description: Description of what this rule monitors rule_type: $ref: "#/RuleType" moderate_threshold: type: integer description: Threshold at which to generate a moderate-level alert minimum: 0 example: 30 high_threshold: type: integer description: Threshold at which to generate a high-level alert minimum: 0 example: 60 critical_threshold: type: integer description: Threshold at which to generate a critical-level alert minimum: 0 example: 90 stable_only: type: boolean description: Only consider stable releases default: true is_active: type: boolean default: true UpdateMonitoringRuleRequest: type: object properties: name: type: string description: type: string rule_type: $ref: "#/RuleType" moderate_threshold: type: integer minimum: 0 high_threshold: type: integer minimum: 0 critical_threshold: type: integer minimum: 0 stable_only: type: boolean is_active: type: boolean ListMonitoringRulesResponse: x-go-name: ListMonitoringRulesResponsePayload type: object required: - rules - limit - offset properties: rules: type: array items: $ref: "#/MonitoringRule" total_count: type: integer format: int32 description: Total number of rules limit: type: integer format: int32 offset: type: integer format: int32 EvaluateRulesResponse: x-go-name: EvaluateRulesResponsePayload type: object required: - configs_evaluated - alerts_created properties: configs_evaluated: type: integer description: Number of alert configs evaluated example: 10 alerts_created: type: integer description: Number of new alerts created example: 3 alerts_updated: type: integer description: Number of existing alerts updated example: 2 errors: type: array items: type: string description: Any errors encountered during evaluation Alert: type: object required: - id - organization_id - alert_config_id - discovered_version - latest_version - behind_by - severity - is_acknowledged properties: id: type: integer format: int64 example: 456 organization_id: type: integer format: int64 example: 1 alert_config_id: type: integer format: int64 description: ID of the alert configuration that generated this alert example: 123 config_name: type: string description: Name of the alert configuration rule_name: type: string description: Name of the monitoring rule rule_type: $ref: "#/RuleType" artifact_name: type: string description: Artifact name from the gather job example: kubernetes/kubernetes scrape_repository_url: type: string description: Repository URL from the scrape job scrape_target_file: type: string description: Target file from the scrape job discovered_version: type: string example: "1.25.0" latest_version: type: string example: "1.30.0" behind_by: type: integer description: How far behind (interpretation depends on rule_type) example: 5 severity: $ref: "#/AlertSeverity" is_acknowledged: type: boolean example: false acknowledged_by: type: integer format: int64 description: User ID who acknowledged the alert acknowledged_at: type: string format: date-time created_at: type: string format: date-time updated_at: type: string format: date-time resolved_at: type: string format: date-time description: When the alert was resolved (soft deleted). Null if alert is still active. ListAlertsResponse: x-go-name: ListAlertsResponsePayload type: object required: - alerts - limit - offset properties: alerts: type: array items: $ref: "#/Alert" total_count: type: integer format: int32 description: Total number of alerts matching the filter limit: type: integer format: int32 offset: type: integer format: int32 AlertConfig: type: object required: - id - organization_id - name - scrape_job_id - gather_job_id - rule_id - is_active properties: id: type: integer format: int64 example: 123 organization_id: type: integer format: int64 example: 1 name: type: string description: Name of the alert configuration example: "K8s Dashboard Version Check" description: type: string description: Description of this alert configuration scrape_job_id: type: integer format: int64 description: ID of the scrape job providing discovered versions example: 456 gather_job_id: type: integer format: int64 description: ID of the gather job providing upstream releases example: 789 rule_id: type: integer format: int64 description: ID of the monitoring rule defining evaluation logic example: 321 rule_name: type: string description: Name of the linked rule rule_type: $ref: "#/RuleType" scrape_repository_url: type: string description: Repository URL from the scrape job scrape_target_file: type: string description: Target file from the scrape job gather_artifact_name: type: string description: Artifact name from the gather job is_active: type: boolean description: Whether the config is active example: true created_at: type: string format: date-time updated_at: type: string format: date-time CreateAlertConfigRequest: type: object required: - name - scrape_job_id - gather_job_id - rule_id properties: name: type: string description: Name of the alert configuration example: "K8s Dashboard Version Check" description: type: string description: Description of this alert configuration scrape_job_id: type: integer format: int64 description: ID of the scrape job gather_job_id: type: integer format: int64 description: ID of the gather job rule_id: type: integer format: int64 description: ID of the monitoring rule is_active: type: boolean default: true UpdateAlertConfigRequest: type: object properties: name: type: string description: type: string scrape_job_id: type: integer format: int64 gather_job_id: type: integer format: int64 rule_id: type: integer format: int64 is_active: type: boolean ListAlertConfigsResponse: x-go-name: ListAlertConfigsResponsePayload type: object required: - configs - limit - offset properties: configs: type: array items: $ref: "#/AlertConfig" total_count: type: integer format: int32 description: Total number of configs limit: type: integer format: int32 offset: type: integer format: int32 ScrapeJobDropdownItem: type: object properties: id: type: integer format: int64 name: type: string description: Human-readable name for this scrape job (optional) repository_url: type: string target_file: type: string GatherJobDropdownItem: type: object properties: id: type: integer format: int64 name: type: string description: Human-readable name for this gather job artifact_name: type: string tag_filter: type: string description: Regex pattern to filter tags version_regex: type: string description: Regex with capture group to extract version from tag RuleDropdownItem: type: object properties: id: type: integer format: int64 name: type: string rule_type: $ref: "#/RuleType" OrgMemberDropdownItem: type: object properties: id: type: integer format: int64 description: User ID display_name: type: string description: Display name (first last, or email) email: type: string description: User email AlertSummary: type: object required: - total_count - unacknowledged_count - moderate_count - high_count - critical_count properties: total_count: type: integer format: int64 description: Total number of alerts example: 10 unacknowledged_count: type: integer format: int64 description: Number of unacknowledged alerts example: 5 moderate_count: type: integer format: int64 description: Number of unacknowledged moderate alerts example: 2 high_count: type: integer format: int64 description: Number of unacknowledged high alerts example: 2 critical_count: type: integer format: int64 description: Number of unacknowledged critical alerts example: 1 BulkAcknowledgeRequest: type: object required: - alert_ids properties: alert_ids: type: array items: type: integer format: int64 description: IDs of alerts to acknowledge example: [1, 2, 3] BulkAcknowledgeResponse: type: object required: - acknowledged_count properties: acknowledged_count: type: integer description: Number of alerts acknowledged example: 3 MetricsResponse: x-go-name: MetricsResponsePayload type: object required: - organization_id - collected_at - gather_jobs - scrape_jobs - alerts - agents - releases - version_drift - task_executions properties: organization_id: type: integer format: int64 description: Organization these metrics are scoped to example: 1 collected_at: type: string format: date-time description: When these metrics were collected gather_jobs: $ref: "#/JobStatusCounts" scrape_jobs: $ref: "#/JobStatusCounts" alerts: $ref: "#/AlertMetrics" agents: $ref: "#/AgentMetrics" releases: $ref: "#/ReleaseMetrics" version_drift: $ref: "#/VersionDriftMetrics" task_executions: $ref: "#/TaskExecutionMetrics" JobStatusCounts: type: object description: Counts of jobs by status properties: pending: type: integer format: int64 description: Number of pending jobs example: 5 queued: type: integer format: int64 description: Number of queued jobs (ready for agent pickup) example: 3 in_progress: type: integer format: int64 description: Number of in-progress jobs example: 2 completed: type: integer format: int64 description: Number of completed jobs example: 150 failed: type: integer format: int64 description: Number of failed jobs example: 3 AlertMetrics: type: object description: Alert statistics properties: total: type: integer format: int64 description: Total number of alerts example: 50 unacknowledged: type: integer format: int64 description: Number of unacknowledged alerts example: 12 by_severity: $ref: "#/AlertSeverityCounts" AlertSeverityCounts: type: object description: Alert counts by severity properties: critical: type: integer format: int64 description: Number of critical alerts example: 2 high: type: integer format: int64 description: Number of high alerts example: 5 moderate: type: integer format: int64 description: Number of moderate alerts example: 5 AgentMetrics: type: object description: Agent statistics properties: total: type: integer format: int64 description: Total number of registered agents example: 4 healthy: type: integer format: int64 description: Number of healthy agents (heartbeat within 5 minutes) example: 3 unhealthy: type: integer format: int64 description: Number of unhealthy agents example: 1 ReleaseMetrics: type: object description: Release statistics properties: total: type: integer format: int64 description: Total number of tracked releases example: 500 stable: type: integer format: int64 description: Number of stable releases example: 450 prerelease: type: integer format: int64 description: Number of prerelease versions example: 50 unique_artifacts: type: integer format: int64 description: Number of unique artifact names example: 25 VersionDriftMetrics: type: object description: Version drift statistics properties: by_rule_type: type: object description: Drift stats grouped by rule type additionalProperties: $ref: "#/RuleTypeDrift" worst_drifts: type: array description: Top worst version drifts items: $ref: "#/DriftDetail" RuleTypeDrift: type: object description: Drift statistics for a specific rule type properties: configs_monitored: type: integer description: Number of alert configs using this rule type example: 10 configs_drifted: type: integer description: Number of configs with active drift alerts example: 3 max_drift: type: integer description: Maximum drift value example: 45 avg_drift: type: number format: float description: Average drift value example: 22.5 DriftDetail: type: object description: Details of a specific version drift properties: alert_config_name: type: string description: Name of the alert configuration example: prod-api-helm-chart rule_type: type: string description: Type of rule (days_behind, majors_behind, minors_behind) example: days_behind discovered_version: type: string description: Currently discovered version example: "1.2.3" latest_version: type: string description: Latest available version example: "1.5.0" behind_by: type: integer description: How far behind (interpretation depends on rule_type) example: 45 severity: type: string description: Alert severity example: critical TaskExecutionMetrics: type: object description: Task execution statistics properties: gather: $ref: "#/JobTypeExecutionStats" scrape: $ref: "#/JobTypeExecutionStats" JobTypeExecutionStats: type: object description: Execution statistics for a job type properties: total: type: integer description: Total executions in the last 24 hours example: 500 completed: type: integer description: Completed executions example: 480 failed: type: integer description: Failed executions example: 15 in_progress: type: integer description: Currently in-progress executions example: 5 success_rate: type: number format: float description: Success rate (0-1) example: 0.97 avg_duration_seconds: type: number format: float description: Average execution duration in seconds example: 12.5 p50_duration_seconds: type: number format: float description: 50th percentile (median) duration example: 8.2 p95_duration_seconds: type: number format: float description: 95th percentile duration example: 35.0 p99_duration_seconds: type: number format: float description: 99th percentile duration example: 58.0 SystemMetricsResponse: x-go-name: SystemMetricsResponsePayload type: object description: System-wide metrics for monitoring and Prometheus scraping required: - collected_at - organizations - services - agents - jobs - alerts - releases - task_executions - api_keys properties: collected_at: type: string format: date-time description: When these metrics were collected organizations: $ref: "#/OrganizationCounts" services: type: array items: $ref: "#/ServiceInstanceCounts" description: Service instances by type with health status agents: $ref: "#/AgentMetrics" jobs: $ref: "#/SystemJobCounts" alerts: $ref: "#/AlertMetrics" releases: $ref: "#/ReleaseMetrics" task_executions: $ref: "#/SystemTaskExecutionMetrics" api_keys: $ref: "#/APIKeyCounts" OrganizationCounts: type: object description: Organization statistics properties: total: type: integer format: int64 description: Total number of organizations example: 5 active: type: integer format: int64 description: Number of active organizations example: 4 ServiceInstanceCounts: type: object description: Service instance counts by type and health properties: service_name: type: string description: Name of the service example: agent total: type: integer format: int64 description: Total instances of this service example: 4 healthy: type: integer format: int64 description: Healthy instances (heartbeat within 5 minutes) example: 3 unhealthy: type: integer format: int64 description: Unhealthy instances example: 1 SystemJobCounts: type: object description: Job counts by type and status (system-wide) properties: gather: $ref: "#/JobStatusCounts" scrape: $ref: "#/JobStatusCounts" helm_sync: $ref: "#/JobStatusCounts" SystemTaskExecutionMetrics: type: object description: Task execution statistics for last 24 hours (system-wide) properties: total: type: integer format: int64 description: Total task executions in last 24 hours example: 500 completed: type: integer format: int64 description: Completed executions example: 480 failed: type: integer format: int64 description: Failed executions example: 15 in_progress: type: integer format: int64 description: Currently in-progress executions example: 5 success_rate: type: number format: float description: Success rate (0-1) example: 0.97 APIKeyCounts: type: object description: API key statistics properties: total: type: integer format: int64 description: Total number of API keys example: 10 active: type: integer format: int64 description: Number of active API keys example: 8 system: type: integer format: int64 description: Number of system API keys example: 2 # Notification System Schemas NotificationChannelType: type: string enum: - webhook - pagerduty - telegram - smtp description: Type of notification channel example: webhook NotificationDeliveryStatus: type: string enum: - pending - in_progress - succeeded - failed - dead_letter description: Status of a notification delivery example: pending NotificationEventType: type: string enum: - alert.created - alert.escalated - alert.acknowledged - alert.unacknowledged - alert.resolved - test description: Type of notification event example: alert.created WebhookConfig: type: object description: Configuration for webhook notification channels required: - url properties: url: type: string format: uri description: Webhook URL to send notifications to example: https://hooks.slack.com/services/xxx method: type: string enum: [POST, PUT, PATCH] default: POST description: HTTP method to use headers: type: object additionalProperties: type: string description: Custom HTTP headers to send example: Authorization: "Bearer xxx" timeout_seconds: type: integer minimum: 1 maximum: 120 default: 30 description: Request timeout in seconds ack_enabled: type: boolean default: true description: Include acknowledgment URL in payload secret: type: string description: HMAC secret for signing payloads event_templates: $ref: "#/WebhookEventTemplates" WebhookEventTemplates: type: object description: | Event-specific body templates for webhooks. Each template is a Go template string with access to event-specific fields. properties: new_alert: type: string description: | Template for new and escalated alerts (alert.created, alert.escalated). Available fields: {{.AcknowledgeURL}}, {{.PreviousSeverity}} (escalated only), plus all standard fields. example: '{"text": "🚨 {{.Alert.Severity | upper}}: {{.Alert.ConfigName}}", "ack": "{{.AcknowledgeURL}}"}' acknowledged: type: string description: | Template for acknowledged alerts (alert.acknowledged, alert.unacknowledged). Available fields: {{.AcknowledgedBy}}, {{.AcknowledgedAt}}. Note: AcknowledgeURL is NOT included for these events. example: '{"text": "✅ Alert acknowledged by {{.AcknowledgedBy}} at {{.AcknowledgedAt}}"}' resolved: type: string description: | Template for resolved alerts (alert.resolved). Available fields: {{.ResolvedAt}}. Note: AcknowledgeURL is NOT included for resolved events. example: '{"text": "🎉 Alert resolved at {{.ResolvedAt}}"}' NotificationChannel: type: object required: - id - organization_id - name - channel_type - is_active properties: id: type: integer format: int64 example: 1 organization_id: type: integer format: int64 example: 1 name: type: string description: Human-readable name for the channel example: Slack Ops description: type: string description: Optional description channel_type: $ref: "#/NotificationChannelType" config: $ref: "#/WebhookConfig" is_active: type: boolean example: true last_test_at: type: string format: date-time description: When the channel was last tested last_test_success: type: boolean description: Whether the last test was successful last_test_error: type: string description: Error message from last test if failed max_retries: type: integer description: Maximum retry attempts for this channel example: 12 require_ack_auth: type: boolean description: Whether acknowledge URLs require login (default true) example: true created_at: type: string format: date-time updated_at: type: string format: date-time CreateNotificationChannelRequest: type: object required: - name - channel_type - config properties: name: type: string description: Human-readable name for the channel example: Slack Ops description: type: string description: Optional description channel_type: $ref: "#/NotificationChannelType" config: $ref: "#/WebhookConfig" is_active: type: boolean default: true max_retries: type: integer minimum: 1 maximum: 20 description: Maximum retry attempts (default 12) require_ack_auth: type: boolean description: Whether acknowledge URLs require login (default true) UpdateNotificationChannelRequest: type: object properties: name: type: string description: type: string nullable: true config: $ref: "#/WebhookConfig" is_active: type: boolean max_retries: type: integer minimum: 1 maximum: 20 nullable: true require_ack_auth: type: boolean description: Whether acknowledge URLs require login ListNotificationChannelsResponse: x-go-name: ListNotificationChannelsResponsePayload type: object required: - channels - limit - offset properties: channels: type: array items: $ref: "#/NotificationChannel" total_count: type: integer format: int32 limit: type: integer format: int32 offset: type: integer format: int32 NotificationRule: type: object required: - id - organization_id - name - is_active - priority properties: id: type: integer format: int64 example: 1 organization_id: type: integer format: int64 example: 1 name: type: string description: Human-readable name for the rule example: Critical PagerDuty description: type: string description: Optional description severity_filter: type: array items: $ref: "#/AlertSeverity" description: Filter by alert severities (empty = all) example: [critical, high] event_filter: type: array items: $ref: "#/NotificationEventType" description: Filter by event types (empty = all) example: [alert.created, alert.escalated] channel_id: type: integer format: int64 nullable: true description: Override channel (null = use org default) channel_name: type: string description: Name of the override channel (if set) channel_type: $ref: "#/NotificationChannelType" group_interval: type: string description: Group alerts within this window (ISO 8601 duration) example: PT5M repeat_interval: type: string description: Don't repeat for same alert within this window example: PT1H is_active: type: boolean example: true priority: type: integer description: Higher priority rules evaluated first example: 10 created_at: type: string format: date-time updated_at: type: string format: date-time CreateNotificationRuleRequest: type: object required: - name properties: name: type: string example: Critical PagerDuty description: type: string severity_filter: type: array items: $ref: "#/AlertSeverity" event_filter: type: array items: $ref: "#/NotificationEventType" channel_id: type: integer format: int64 nullable: true group_interval: type: string default: PT5M repeat_interval: type: string default: PT1H is_active: type: boolean default: true priority: type: integer default: 0 UpdateNotificationRuleRequest: type: object properties: name: type: string description: type: string nullable: true severity_filter: type: array items: $ref: "#/AlertSeverity" event_filter: type: array items: $ref: "#/NotificationEventType" channel_id: type: integer format: int64 nullable: true group_interval: type: string repeat_interval: type: string is_active: type: boolean priority: type: integer ListNotificationRulesResponse: x-go-name: ListNotificationRulesResponsePayload type: object required: - rules - limit - offset properties: rules: type: array items: $ref: "#/NotificationRule" total_count: type: integer format: int32 limit: type: integer format: int32 offset: type: integer format: int32 NotificationDelivery: type: object required: - id - organization_id - alert_id - channel_id - status - event_type - attempts properties: id: type: integer format: int64 organization_id: type: integer format: int64 alert_id: type: integer format: int64 channel_id: type: integer format: int64 channel_name: type: string channel_type: $ref: "#/NotificationChannelType" rule_id: type: integer format: int64 nullable: true rule_name: type: string status: $ref: "#/NotificationDeliveryStatus" event_type: type: string alert_severity: $ref: "#/AlertSeverity" request_payload: type: object description: The notification payload that was/will be sent response_status: type: integer description: HTTP status code from delivery attempt response_body: type: string description: Response body from delivery attempt error_message: type: string description: Error message if delivery failed idempotency_key: type: string format: uuid description: Stable key for deduplication attempts: type: integer description: Number of delivery attempts next_retry_at: type: string format: date-time sent_at: type: string format: date-time description: When successfully sent created_at: type: string format: date-time updated_at: type: string format: date-time ListNotificationDeliveriesResponse: x-go-name: ListNotificationDeliveriesResponsePayload type: object required: - deliveries - limit - offset properties: deliveries: type: array items: $ref: "#/NotificationDelivery" total_count: type: integer format: int32 limit: type: integer format: int32 offset: type: integer format: int32 NotificationChannelTestResult: type: object required: - success - tested_at properties: success: type: boolean connectivity_check: type: object properties: status: type: integer latency_ms: type: integer format: int64 error: type: string sample_delivery: type: object properties: status: type: integer latency_ms: type: integer format: int64 response_preview: type: string error: type: string tested_at: type: string format: date-time idempotency_key: type: string error: type: string validation_errors: type: array items: type: string NotificationChannelStats: type: object properties: id: type: integer format: int64 name: type: string deliveries_24h: type: integer format: int64 succeeded_24h: type: integer format: int64 failed_24h: type: integer format: int64 dead_letter_24h: type: integer format: int64 success_rate_24h: type: number format: float description: Success rate in last 24 hours (0-1) NotificationRuleStats: type: object properties: id: type: integer format: int64 name: type: string matches_24h: type: integer format: int64 matches_7d: type: integer format: int64 NotificationSettings: type: object properties: default_channel_id: type: integer format: int64 nullable: true description: Default channel when no rules match default_channel_name: type: string description: Name of the default channel UpdateNotificationSettingsRequest: type: object properties: default_channel_id: type: integer format: int64 nullable: true NotificationDeliveryQueueStats: type: object properties: pending_count: type: integer format: int64 in_progress_count: type: integer format: int64 failed_count: type: integer format: int64 dead_letter_count: type: integer format: int64 WebhookAcknowledgeResponse: type: object required: - success - alert_id properties: success: type: boolean alert_id: type: integer format: int64 message: type: string ValidateWebhookConfigRequest: type: object required: - config properties: config: $ref: "#/WebhookConfig" WebhookConfigValidationResult: type: object required: - valid properties: valid: type: boolean errors: type: array items: type: string NotificationChannelDropdownItem: type: object required: - id - name - channel_type properties: id: type: integer format: int64 name: type: string channel_type: $ref: "#/NotificationChannelType" SimulateNotificationRuleRequest: type: object required: - alert_severity - event_type properties: alert_severity: $ref: "#/AlertSeverity" event_type: $ref: "#/NotificationEventType" NotificationRuleSimulationResult: type: object required: - matches properties: matches: type: boolean matching_channels: type: array items: $ref: "#/NotificationChannelDropdownItem" preview_payload: type: string description: JSON preview of the notification payload NotificationTemplateCategory: type: string enum: - new_alert - acknowledged - resolved description: | Template category for notification events: - new_alert: For alert.created and alert.escalated events - acknowledged: For alert.acknowledged and alert.unacknowledged events - resolved: For alert.resolved events NotificationTemplateInfo: type: object required: - category - source properties: category: $ref: "#/NotificationTemplateCategory" template: type: string description: The template content (empty string means use JSON payload) source: type: string enum: - global - organization description: Where this template comes from (global default or org override) available_fields: type: array items: type: string description: Fields available in this template category example: ["{{.Alert.Severity}}", "{{.AcknowledgeURL}}"] event_types: type: array items: type: string description: Event types this template applies to example: ["alert.created", "alert.escalated"] ListNotificationTemplatesResponse: x-go-name: ListNotificationTemplatesResponsePayload type: object required: - templates properties: templates: type: array items: $ref: "#/NotificationTemplateInfo" UpdateNotificationTemplateRequest: type: object required: - template properties: template: type: string description: | The Go template string. Use empty string to clear the org override and fall back to global default. example: '{"text": "🚨 {{.Alert.Severity | upper}}: {{.Alert.ConfigName}}"}' NotificationTemplatePreviewRequest: type: object required: - template - category properties: template: type: string description: The template to preview category: $ref: "#/NotificationTemplateCategory" NotificationTemplatePreviewResponse: type: object required: - success properties: success: type: boolean rendered: type: string description: The rendered template output error: type: string description: Error message if template is invalid AgentSubmissionLog: type: object required: - id - agent_uuid - submission_type - created_at properties: id: type: integer format: int64 job_id: type: integer format: int64 nullable: true agent_uuid: type: string format: uuid submission_type: type: string description: Type of submission (e.g., complete, log-failure) response_status: type: integer nullable: true description: HTTP response status code error_message: type: string nullable: true description: Error message if submission failed created_at: type: string format: date-time ListAgentSubmissionLogsResponse: x-go-name: ListAgentSubmissionLogsResponsePayload type: object required: - logs properties: logs: type: array items: $ref: "#/AgentSubmissionLog" # API Key Management APIKey: type: object required: - id - organization_id - name - is_active - created_at properties: id: type: integer format: int64 organization_id: type: integer format: int64 user_id: type: integer format: int64 nullable: true name: type: string description: type: string nullable: true is_active: type: boolean key_prefix: type: string description: Visual key identifier (e.g., pk_123_...) expires_at: type: string format: date-time nullable: true last_used_at: type: string format: date-time nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time CreateAPIKeyRequest: type: object required: - name properties: name: type: string description: Human-readable name for this API key description: type: string description: Optional description expires_at: type: string format: date-time description: Optional expiration time UpdateAPIKeyRequest: type: object properties: name: type: string description: type: string CreateAPIKeyResponse: x-go-name: CreateAPIKeyResponsePayload type: object required: - api_key - plaintext_key properties: api_key: $ref: "#/APIKey" plaintext_key: type: string description: The full API key string. Only shown once at creation time. ListAPIKeysResponse: x-go-name: ListAPIKeysResponsePayload type: object required: - api_keys - limit - offset properties: api_keys: type: array items: $ref: "#/APIKey" total_count: type: integer format: int32 limit: type: integer format: int32 offset: type: integer format: int32 # === Feedback Schemas === FeedbackCategory: type: string enum: - bug_report - feature_request - general - ui_ux description: Category of user feedback CreateFeedbackRequest: type: object required: - category - message properties: category: $ref: "#/FeedbackCategory" message: type: string maxLength: 5000 description: The feedback message content CreateFeedbackResponse: x-go-name: CreateFeedbackResponsePayload type: object required: - id - category - message - created_at properties: id: type: integer format: int64 category: $ref: "#/FeedbackCategory" message: type: string created_at: type: string format: date-time Feedback: type: object required: - id - organization_id - category - message - created_at properties: id: type: integer format: int64 organization_id: type: integer format: int64 user_id: type: integer format: int64 user_email: type: string organization_name: type: string category: $ref: "#/FeedbackCategory" message: type: string created_at: type: string format: date-time ListFeedbackResponse: x-go-name: ListFeedbackResponsePayload type: object required: - items - total_count - limit - offset properties: items: type: array items: $ref: "#/Feedback" total_count: type: integer format: int64 limit: type: integer format: int32 offset: type: integer format: int32 # Audit Trail AuditTrailEntry: type: object required: - id - organization_id - entity_type - entity_id - action_type - source - created_at properties: id: type: integer format: int64 organization_id: type: integer format: int64 entity_type: type: string description: "Entity type: alert, gather_job, scrape_job, etc." entity_id: type: integer format: int64 action_type: type: string description: "Type of action: created, escalated, acknowledge, unacknowledge, resolve" actor_email: type: string description: "Email of the user who performed the action" source: type: string description: "Where the action originated: api, ui, webhook, system" metadata: type: object additionalProperties: true description: "Additional context (IP, user agent, etc.)" created_at: type: string format: date-time ListAuditTrailResponse: type: object required: - entries - total_count - limit - offset properties: entries: type: array items: $ref: "#/AuditTrailEntry" total_count: type: integer format: int32 limit: type: integer format: int32 offset: type: integer format: int32 # === EOL Product Schemas === EOLProductStatus: type: string enum: - approved - denied - pending description: Status of an EOL product EOLProduct: type: object required: - id - slug - status - created_at properties: id: type: integer format: int64 slug: type: string description: Product slug from endoflife.date example: kubernetes status: $ref: "#/EOLProductStatus" last_synced_at: type: string format: date-time nullable: true sync_error: type: string nullable: true created_at: type: string format: date-time EOLProductsList: type: object required: - items - total properties: items: type: array items: $ref: "#/EOLProduct" total: type: integer format: int64 description: Total number of products matching the filter EOLSyncRun: type: object required: - id - sync_started_at - total_products - processed_products - failed_products - status properties: id: type: integer format: int64 sync_started_at: type: string format: date-time sync_completed_at: type: string format: date-time nullable: true total_products: type: integer format: int32 processed_products: type: integer format: int32 failed_products: type: integer format: int32 status: type: string description: Sync run status (running, completed, completed_with_errors, cancelled, failed) error_message: type: string nullable: true EOLSyncHistory: type: object required: - items properties: items: type: array items: $ref: "#/EOLSyncRun" EOLSyncTriggerResponse: type: object required: - message properties: message: type: string description: Status message example: Sync started # User management (Internal API) AdminUser: type: object required: - id - email - is_active - is_approved - is_superadmin - created_at properties: id: type: integer format: int64 email: type: string example: admin@example.com first_name: type: string nullable: true last_name: type: string nullable: true is_active: type: boolean is_approved: type: boolean is_superadmin: type: boolean created_at: type: string format: date-time last_login_at: type: string format: date-time nullable: true AdminUserList: type: object required: - items properties: items: type: array items: $ref: "#/AdminUser" UserOrgRole: type: object required: - role_key - domain - org_name properties: role_key: type: string example: "role:admin" domain: type: string example: "org:1" org_name: type: string example: "Acme Corp" UserOrgRoles: type: object required: - items properties: items: type: array items: $ref: "#/UserOrgRole" # Integration test results (Internal API) IntegrationTestRun: type: object required: - id - status - total_tests - passed_tests - failed_tests - skipped_tests - duration_ms - started_at - created_at properties: id: type: integer format: int64 status: type: string description: "Test run status: running, passed, failed" example: passed total_tests: type: integer format: int32 passed_tests: type: integer format: int32 failed_tests: type: integer format: int32 skipped_tests: type: integer format: int32 duration_ms: type: integer format: int64 git_commit: type: string nullable: true version: type: string nullable: true started_at: type: string format: date-time completed_at: type: string format: date-time nullable: true created_at: type: string format: date-time IntegrationTestRunsList: type: object required: - items properties: items: type: array items: $ref: "#/IntegrationTestRun" IntegrationTestCase: type: object required: - id - test_name - package - status - duration_ms properties: id: type: integer format: int64 test_name: type: string example: TestListGatherJobsOrGlobal package: type: string example: github.com/sqljames/planekeeper/pkg/storage/repository status: type: string description: "Test case status: pass, fail, skip" example: pass duration_ms: type: integer format: int64 output: type: string nullable: true IntegrationTestRunDetail: type: object required: - run - cases properties: run: $ref: "#/IntegrationTestRun" cases: type: array items: $ref: "#/IntegrationTestCase"