openapi: 3.0.3 info: title: Containr API description: | Self-hosted PaaS on Proxmox - Railway-like platform for container orchestration and deployment. ## Overview Containr provides a comprehensive platform for deploying, managing, and scaling containerized applications on Proxmox infrastructure. This API allows you to manage projects, services, deployments, databases, and more through a RESTful interface. ## Authentication The API uses JWT-based authentication. Include your JWT token in the Authorization header: ``` Authorization: Bearer ``` ## Base URL ``` https://your-containr-domain.com/api/v1 ``` version: 1.0.0 contact: name: Containr Documentation url: https://github.com/your-org/containr license: name: MIT url: https://opensource.org/licenses/MIT servers: - url: http://localhost:8080/api/v1 description: Development server - url: https://your-containr-domain.com/api/v1 description: Production server paths: # Health Check /health: servers: - url: http://localhost:8080 get: tags: - Health summary: Health check endpoint description: 'Served at the root, outside /api/v1. Returns dependency status: {"checks":{"database":"ok","redis":"ok"},"service":"containr-api","status":"ok"}' responses: '200': description: Service is healthy content: application/json: schema: $ref: '#/components/schemas/HealthResponse' # Authentication /auth/login: post: tags: - Authentication summary: User login description: Authenticate user and return JWT token requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LoginRequest' responses: '200': description: Login successful content: application/json: schema: $ref: '#/components/schemas/LoginResponse' '401': description: Invalid credentials content: application/json: schema: $ref: '#/components/schemas/Error' /auth/register: post: tags: - Authentication summary: User registration description: Register a new user account requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterRequest' responses: '201': description: Registration successful content: application/json: schema: $ref: '#/components/schemas/User' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' # User Management /user/profile: get: tags: - User summary: Get user profile description: Retrieve current user's profile information security: - bearerAuth: [] responses: '200': description: Profile retrieved successfully content: application/json: schema: $ref: '#/components/schemas/User' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - User summary: Update user profile description: Update current user's profile information security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateUserRequest' responses: '200': description: Profile updated successfully content: application/json: schema: $ref: '#/components/schemas/User' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' # Projects /projects: get: tags: - Projects summary: List projects description: Retrieve all projects accessible to the current user security: - bearerAuth: [] parameters: - name: page in: query description: Page number for pagination schema: type: integer default: 1 - name: limit in: query description: Number of items per page schema: type: integer default: 20 - name: search in: query description: Search term to filter projects schema: type: string responses: '200': description: Projects retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ProjectsResponse' post: tags: - Projects summary: Create project description: Create a new project security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateProjectRequest' responses: '201': description: Project created successfully content: application/json: schema: $ref: '#/components/schemas/Project' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /projects/{id}: get: tags: - Projects summary: Get project description: Retrieve a specific project by ID security: - bearerAuth: [] parameters: - name: id in: path required: true description: Project ID schema: type: string responses: '200': description: Project retrieved successfully content: application/json: schema: $ref: '#/components/schemas/Project' '404': description: Project not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Projects summary: Update project description: Update a specific project security: - bearerAuth: [] parameters: - name: id in: path required: true description: Project ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateProjectRequest' responses: '200': description: Project updated successfully content: application/json: schema: $ref: '#/components/schemas/Project' '404': description: Project not found content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - Projects summary: Delete project description: Delete a specific project security: - bearerAuth: [] parameters: - name: id in: path required: true description: Project ID schema: type: string responses: '204': description: Project deleted successfully '404': description: Project not found content: application/json: schema: $ref: '#/components/schemas/Error' # Services /projects/{id}/services: get: tags: - Services summary: List project services description: Retrieve all services in a project security: - bearerAuth: [] parameters: - name: id in: path required: true description: Project ID schema: type: string responses: '200': description: Services retrieved successfully content: application/json: schema: type: array items: $ref: '#/components/schemas/Service' post: tags: - Services summary: Create service description: Create a new service in a project security: - bearerAuth: [] parameters: - name: id in: path required: true description: Project ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateServiceRequest' responses: '201': description: Service created successfully content: application/json: schema: $ref: '#/components/schemas/Service' /services/{id}: get: tags: - Services summary: Get service description: Retrieve a specific service security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string responses: '200': description: Service retrieved successfully content: application/json: schema: $ref: '#/components/schemas/Service' put: tags: - Services summary: Update service description: Update a specific service security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateServiceRequest' responses: '200': description: Service updated successfully content: application/json: schema: $ref: '#/components/schemas/Service' delete: tags: - Services summary: Delete service description: Delete a specific service security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string responses: '204': description: Service deleted successfully /services/{id}/runtime: get: tags: - Services summary: Service runtime state description: Live container state — replicas, URLs, aggregate status security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: Runtime state content: application/json: schema: type: object properties: runtime: type: object properties: desired: type: integer status: type: string enum: [running, degraded, stopped] urls: type: array items: type: string containers: type: array items: type: object properties: id: type: string name: type: string state: type: string replica: type: integer /services/{id}/start: post: tags: - Services summary: Start service description: Start all stopped replicas security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: Service started /services/{id}/stop: post: tags: - Services summary: Stop service description: Stop all replicas without removing them security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: Service stopped /services/{id}/restart: post: tags: - Services summary: Restart service description: Restart all replicas security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: Service restarted /services/{id}/redeploy: post: tags: - Services summary: Redeploy service description: Re-apply the current spec — pulls the image for image-sourced services, reuses the last deployed image otherwise security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: Reconciled runtime state /services/{id}/deployments: get: tags: - Deployments summary: List deployments description: Retrieve recent deployments for a specific service security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string responses: '200': description: Deployments retrieved successfully content: application/json: schema: $ref: '#/components/schemas/DeploymentListResponse' post: tags: - Deployments summary: Create deployment description: Trigger a new deployment for a service security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/CreateDeploymentRequest' responses: '201': description: Deployment created successfully content: application/json: schema: $ref: '#/components/schemas/Deployment' /deployments/{id}: get: tags: - Deployments summary: Get deployment description: Retrieve a deployment with build/runtime details security: - bearerAuth: [] parameters: - name: id in: path required: true description: Deployment ID schema: type: string responses: '200': description: Deployment retrieved successfully content: application/json: schema: type: object properties: deployment: $ref: '#/components/schemas/Deployment' /deployments/{id}/rollback: post: tags: - Deployments summary: Rollback deployment description: Create a rollback deployment from a previous deployment security: - bearerAuth: [] parameters: - name: id in: path required: true description: Deployment ID schema: type: string responses: '201': description: Rollback initiated content: application/json: schema: $ref: '#/components/schemas/RollbackDeploymentResponse' /services/{id}/logs: get: tags: - Logs summary: Get service logs description: Retrieve service container logs security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string - name: follow in: query required: false description: Stream logs continuously over SSE schema: type: boolean default: false - name: tail in: query required: false description: Number of recent log lines to fetch schema: type: string default: '100' responses: '200': description: Service logs retrieved successfully content: application/json: schema: $ref: '#/components/schemas/ServiceLogsResponse' /services/{id}/exec: post: tags: - Services summary: Execute command in service container description: Runs a one-off shell command via docker exec and returns captured output. 30s ceiling, 64KB output cap. For debugging only. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Service ID schema: type: string requestBody: required: true content: application/json: schema: type: object required: - command properties: command: type: string description: Shell command (executed via sh -c) maxLength: 4096 responses: '200': description: Command executed (check exit_code/error for failure) content: application/json: schema: type: object properties: output: type: string exit_code: type: integer error: type: string '400': description: Invalid request '404': description: Service not found '409': description: No running container for this service '503': description: Docker unavailable /deployments/{id}/logs: get: tags: - Logs summary: Get deployment logs description: Retrieve build/runtime logs for a deployment security: - bearerAuth: [] parameters: - name: id in: path required: true description: Deployment ID schema: type: string - name: type in: query required: false description: Select log stream schema: type: string enum: [all, build, runtime] default: all responses: '200': description: Deployment logs retrieved successfully content: application/json: schema: $ref: '#/components/schemas/DeploymentLogsResponse' # Builds /builds: get: tags: - Builds summary: List builds description: Retrieve builds with optional filtering and pagination security: - bearerAuth: [] parameters: - name: project_id in: query description: Filter by project ID schema: type: string - name: service_id in: query description: Filter by service ID schema: type: string - name: status in: query description: Filter by build status schema: type: string enum: [pending, running, success, failed, cancelled] - name: page in: query description: 1-based page number schema: type: integer minimum: 1 default: 1 - name: limit in: query description: Number of items per page (max 100) schema: type: integer minimum: 1 maximum: 100 default: 20 responses: '200': description: Builds retrieved successfully content: application/json: schema: $ref: '#/components/schemas/BuildListResponse' post: tags: - Builds summary: Start build description: Start a new build security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StartBuildRequest' responses: '201': description: Build started successfully content: application/json: schema: $ref: '#/components/schemas/StartBuildResponse' /builds/{id}: get: tags: - Builds summary: Get build status description: Retrieve build status and details security: - bearerAuth: [] parameters: - name: id in: path required: true description: Build ID schema: type: string responses: '200': description: Build status retrieved successfully content: application/json: schema: $ref: '#/components/schemas/BuildStatus' /builds/{id}/cancel: post: tags: - Builds summary: Cancel build description: Cancel an in-progress build security: - bearerAuth: [] parameters: - name: id in: path required: true description: Build ID schema: type: string responses: '200': description: Build cancelled content: application/json: schema: $ref: '#/components/schemas/BuildCancelResponse' /builds/{id}/logs: get: tags: - Builds summary: Get build logs description: Retrieve build logs security: - bearerAuth: [] parameters: - name: id in: path required: true description: Build ID schema: type: string - name: follow in: query required: false description: Follow logs in realtime (currently returns same text output) schema: type: boolean default: false responses: '200': description: Build logs retrieved successfully content: text/plain: schema: type: string # Templates /templates: get: tags: - Templates summary: List templates description: Retrieve service templates with optional category filter security: - bearerAuth: [] parameters: - name: category in: query required: false description: Filter templates by category schema: type: string responses: '200': description: Templates retrieved successfully content: application/json: schema: type: object properties: templates: type: array items: $ref: '#/components/schemas/ServiceTemplate' /templates/{id}: get: tags: - Templates summary: Get template description: Retrieve a specific template with parsed config and variables security: - bearerAuth: [] parameters: - name: id in: path required: true description: Template ID schema: type: string responses: '200': description: Template retrieved successfully content: application/json: schema: $ref: '#/components/schemas/TemplateDetailResponse' /templates/{id}/deploy: post: tags: - Templates summary: Create resource from template description: | Create a new resource in a project using a selected template. For `database` templates, this creates a managed database service. security: - bearerAuth: [] parameters: - name: id in: path required: true description: Template ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DeployTemplateRequest' responses: '201': description: Service created from template content: application/json: schema: $ref: '#/components/schemas/DeployTemplateResponse' # Agent Onboarding Tokens /agent-tokens: post: tags: - Agents summary: Issue agent onboarding token description: Generates a new agent onboarding token. The raw token is returned once and never stored — only its SHA-256 hash persists. security: - bearerAuth: [] requestBody: required: false content: application/json: schema: $ref: '#/components/schemas/CreateAgentTokenRequest' responses: '201': description: Token issued; raw value returned once content: application/json: schema: $ref: '#/components/schemas/AgentAuthTokenCreated' get: tags: - Agents summary: List agent onboarding tokens description: Returns issued onboarding token metadata (never token values or hashes). security: - bearerAuth: [] responses: '200': description: Token list content: application/json: schema: type: object properties: tokens: type: array items: $ref: '#/components/schemas/AgentAuthToken' /agent-tokens/{id}: delete: tags: - Agents summary: Revoke agent onboarding token description: Marks a token as revoked. Agents presenting it are rejected from then on. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Token revoked content: application/json: schema: type: object properties: status: type: string id: type: string '404': description: Token not found content: application/json: schema: $ref: '#/components/schemas/Error' # Notifications /notifications: get: tags: - Notifications summary: List notifications for the current user security: - bearerAuth: [] parameters: - name: limit in: query schema: type: integer default: 20 responses: '200': description: Notifications and unread count content: application/json: schema: $ref: '#/components/schemas/NotificationListResponse' /notifications/{id}/read: post: tags: - Notifications summary: Mark a notification as read security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Marked read content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /notifications/read-all: post: tags: - Notifications summary: Mark all notifications as read security: - bearerAuth: [] responses: '200': description: All marked read content: application/json: schema: $ref: '#/components/schemas/MessageResponse' # Audit Logs /audit-logs: get: tags: - Audit summary: List audit logs description: Retrieve audit log entries with optional filters security: - bearerAuth: [] parameters: - name: resource in: query required: false description: Filter audit logs by resource type schema: type: string - name: actor in: query required: false description: Filter audit logs by actor email substring schema: type: string - name: user_id in: query required: false description: Filter audit logs by actor user UUID schema: type: string format: uuid - name: since in: query required: false description: Only return entries created at or after this RFC3339 timestamp schema: type: string format: date-time - name: action in: query required: false description: Filter audit logs by action type schema: type: string - name: page in: query required: false description: 1-based page number schema: type: integer minimum: 1 default: 1 - name: limit in: query required: false description: Number of entries per page schema: type: integer minimum: 1 maximum: 100 default: 50 responses: '200': description: Audit logs retrieved successfully content: application/json: schema: $ref: '#/components/schemas/AuditLogListResponse' /audit-logs/{resource}/{id}: get: tags: - Audit summary: List resource audit logs description: Retrieve audit log entries for a specific resource and resource ID security: - bearerAuth: [] parameters: - name: resource in: path required: true description: Resource type schema: type: string - name: id in: path required: true description: Resource ID schema: type: string responses: '200': description: Resource audit logs retrieved successfully content: application/json: schema: $ref: '#/components/schemas/AuditLogListResponse' # Databases /databases: get: tags: - Databases summary: List databases description: Retrieve all managed databases for the authenticated user security: - bearerAuth: [] responses: '200': description: Databases retrieved successfully content: application/json: schema: $ref: '#/components/schemas/DatabaseListResponse' post: tags: - Databases summary: Create database description: Create a new managed database and start provisioning security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateDatabaseRequest' responses: '201': description: Database provisioning started content: application/json: schema: $ref: '#/components/schemas/DatabaseCreateResponse' /databases/{id}: get: tags: - Databases summary: Get database description: Retrieve a specific database security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string responses: '200': description: Database retrieved successfully content: application/json: schema: $ref: '#/components/schemas/Database' put: tags: - Databases summary: Update database description: Update mutable database metadata (name or plan) security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateDatabaseRequest' responses: '200': description: Database updated successfully content: application/json: schema: $ref: '#/components/schemas/MessageResponse' delete: tags: - Databases summary: Delete database description: Delete managed database and associated runtime security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string responses: '200': description: Database deleted successfully content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /databases/{id}/action: post: tags: - Databases summary: Execute database action description: Execute start, stop, or restart action for a managed database security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DatabaseActionRequest' responses: '200': description: Action accepted content: application/json: schema: $ref: '#/components/schemas/DatabaseActionResponse' /databases/{id}/backup: post: tags: - Databases summary: Create backup description: Create a managed snapshot backup for a database security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string responses: '201': description: Backup started content: application/json: schema: $ref: '#/components/schemas/DatabaseBackupCreateResponse' /databases/{id}/restore: post: tags: - Databases summary: Restore backup description: Restore a managed database from a completed backup security: - bearerAuth: [] parameters: - name: id in: path required: true description: Database ID schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DatabaseRestoreRequest' responses: '200': description: Restore started content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /databases/{id}/backups/{bid}/download: get: tags: - Databases summary: Download a completed backup archive parameters: - name: id in: path required: true schema: type: string - name: bid in: path required: true schema: type: string security: - bearerAuth: [] responses: '200': description: Backup archive stream content: application/gzip: schema: type: string format: binary '404': description: Backup not found content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: Backup not completed content: application/json: schema: $ref: '#/components/schemas/Error' # Git Integration /git/providers: get: tags: - Git summary: List Git providers description: Retrieve available Git providers security: - bearerAuth: [] responses: '200': description: Git providers retrieved successfully content: application/json: schema: type: array items: $ref: '#/components/schemas/GitProvider' post: tags: - Git summary: Add Git provider description: Add a new Git provider security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateGitProviderRequest' responses: '201': description: Git provider added successfully content: application/json: schema: $ref: '#/components/schemas/GitProvider' /git/providers/{providerId}/repositories: get: tags: - Git summary: List repositories description: Retrieve repositories from a Git provider security: - bearerAuth: [] parameters: - name: providerId in: path required: true description: Git provider ID schema: type: string responses: '200': description: Repositories retrieved successfully content: application/json: schema: type: array items: $ref: '#/components/schemas/GitRepository' # Top-level probes (served outside /api/v1) /live: servers: - url: http://localhost:8080 get: tags: - Health summary: Liveness probe description: Process liveness check served at the root, outside /api/v1. responses: '200': description: Process is alive /ready: servers: - url: http://localhost:8080 get: tags: - Health summary: Readiness probe description: Same handler as /health — reports database and Redis status. responses: '200': description: Service is ready content: application/json: schema: $ref: '#/components/schemas/HealthResponse' # Authentication /auth/bootstrap: get: tags: - Authentication summary: Bootstrap status description: Reports whether the instance already has a registered user, which auth providers are configured, and whether public registration is open. Drives the first-run setup gate. responses: '200': description: Bootstrap state content: application/json: schema: type: object properties: has_users: type: boolean description: True when at least one account exists user_count: type: integer mode: type: string enum: [register, login] description: register when the instance has no users, login otherwise providers: type: array items: type: string description: OAuth providers with real credentials configured (e.g. github, google). Empty on self-hosted installs. signup_enabled: type: boolean description: True when the owner re-opened public registration in Settings /settings: get: tags: - Settings summary: Read platform settings description: Admin only. Returns in-app settings that override environment variables. security: - bearerAuth: [] responses: '200': description: Current platform settings content: application/json: schema: $ref: '#/components/schemas/PlatformSettings' '403': description: Admin access required put: tags: - Settings summary: Update platform settings description: Admin only. Provided keys are applied immediately; the Cloudflare tunnel token starts/stops the managed cloudflared sidecar. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: signup_enabled: type: boolean description: Allow new public account registration after bootstrap cloudflare_tunnel_token: type: string description: Cloudflare Tunnel token. Empty string clears the stored token and removes the cloudflared container. responses: '200': description: Updated platform settings content: application/json: schema: $ref: '#/components/schemas/PlatformSettings' '403': description: Admin access required # User Management /users: post: tags: - User summary: Create user (manual) description: Manually create a user account. Used for internal/admin user creation outside the bootstrap flow. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ManualUserCreateRequest' responses: '201': description: User created content: application/json: schema: $ref: '#/components/schemas/User' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' # Services /services/{id}/metrics: get: tags: - Services summary: Service metrics description: Live resource usage for the service's containers (CPU, memory, network, block I/O via Docker stats). security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Current service metrics content: application/json: schema: type: object properties: metrics: $ref: '#/components/schemas/ServiceMetrics' '404': description: Service not found content: application/json: schema: $ref: '#/components/schemas/Error' /services/{id}/variables: get: tags: - Services summary: List service variables description: Environment variables for a service. Secret values are masked. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string format: uuid responses: '200': description: Variables retrieved content: application/json: schema: type: object properties: variables: type: array items: $ref: '#/components/schemas/ServiceVariable' '404': description: Service not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Services summary: Replace service variables description: Replace the full variable set for a service. security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateVariablesRequest' responses: '200': description: Variables updated content: application/json: schema: type: object properties: variables: type: array items: $ref: '#/components/schemas/ServiceVariable' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' # Git integration /git/github-app/install-url: get: tags: - Git summary: GitHub App install URL description: Returns the URL to install the Containr GitHub App, or 404 when no app is configured. security: - bearerAuth: [] responses: '200': description: Install URL content: application/json: schema: type: object properties: install_url: type: string format: uri '404': description: GitHub App not configured content: application/json: schema: $ref: '#/components/schemas/Error' /git/github-app/connect: post: tags: - Git summary: Connect GitHub App installation description: Register a completed GitHub App installation as a git provider. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConnectGitHubAppRequest' responses: '201': description: Provider created content: application/json: schema: $ref: '#/components/schemas/GitProvider' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /git/providers/{providerId}: delete: tags: - Git summary: Delete git provider description: Remove a git provider and its stored credentials. security: - bearerAuth: [] parameters: - name: providerId in: path required: true schema: type: string responses: '200': description: Provider deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' '404': description: Provider not found content: application/json: schema: $ref: '#/components/schemas/Error' /git/providers/{providerId}/repositories/{owner}/{repo}/branches: get: tags: - Git summary: List repository branches description: List branches for a repository through the provider API. security: - bearerAuth: [] parameters: - name: providerId in: path required: true schema: type: string - name: owner in: path required: true schema: type: string - name: repo in: path required: true schema: type: string responses: '200': description: Branches retrieved content: application/json: schema: type: object properties: branches: type: array items: $ref: '#/components/schemas/GitBranch' '502': description: Provider API error content: application/json: schema: $ref: '#/components/schemas/Error' /git/repositories/connect: post: tags: - Git summary: Connect repository description: Connect a provider repository so it can back services and webhooks. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ConnectGitRepoRequest' responses: '201': description: Repository connected content: application/json: schema: $ref: '#/components/schemas/GitRepository' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /git/repositories: get: tags: - Git summary: List connected repositories description: Repositories connected to Containr across all providers. security: - bearerAuth: [] responses: '200': description: Connected repositories content: application/json: schema: type: object properties: repositories: type: array items: $ref: '#/components/schemas/GitRepository' /git/webhooks: post: tags: - Git summary: Create webhook description: Register a webhook on a connected repository to trigger deployments on push. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateWebhookRequest' responses: '201': description: Webhook created content: application/json: schema: $ref: '#/components/schemas/GitWebhook' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' # Builds /builds/plan: post: tags: - Builds summary: Preview build plan description: Resolve how a build would run (detected build type, commands) without executing it. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BuildRequest' responses: '200': description: Resolved build plan content: application/json: schema: type: object properties: plan: type: object description: Detected build type, commands, and resolved options '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /builds/detect: get: tags: - Builds summary: Detect build type description: Auto-detect the build strategy (Dockerfile, Railpack, etc.) for a source path. security: - bearerAuth: [] parameters: - name: source_path in: query schema: type: string responses: '200': description: Detected build type content: application/json: schema: type: object properties: build_type: type: string detected: type: boolean # System /system/upgrade/status: get: tags: - System summary: Upgrade status description: Current version, latest available image, and whether an upgrade is in progress. security: - bearerAuth: [] responses: '200': description: Upgrade status content: application/json: schema: $ref: '#/components/schemas/UpgradeStatus' /system/upgrade/pull: post: tags: - System summary: Pull upgrade image description: Pull the latest Containr image and restart the stack to self-upgrade. security: - bearerAuth: [] responses: '200': description: Upgrade started content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /system/host: get: tags: - System summary: Host monitoring description: 'Host-level telemetry: CPU, memory, disk, network, uptime, and container counts.' security: - bearerAuth: [] responses: '200': description: Host metrics content: application/json: schema: $ref: '#/components/schemas/HostMonitoring' # WebSocket /ws: get: tags: - Realtime summary: WebSocket stream description: Upgrades to WebSocket. Streams build status, deployment events, and container log output. security: - bearerAuth: [] responses: '101': description: WebSocket upgrade '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' # Autoscaling /scaling/policies: get: tags: - Scaling summary: List scaling policies security: - bearerAuth: [] responses: '200': description: All scaling policies content: application/json: schema: type: object properties: policies: type: array items: $ref: '#/components/schemas/ScalingPolicy' count: type: integer post: tags: - Scaling summary: Create or replace scaling policy security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ScalingPolicy' responses: '201': description: Policy stored content: application/json: schema: type: object properties: message: type: string policy: $ref: '#/components/schemas/ScalingPolicy' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /scaling/policies/{serviceId}: get: tags: - Scaling summary: Get scaling policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Scaling policy content: application/json: schema: type: object properties: policy: $ref: '#/components/schemas/ScalingPolicy' '404': description: Policy not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Scaling summary: Update scaling policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ScalingPolicy' responses: '200': description: Policy updated content: application/json: schema: type: object properties: policy: $ref: '#/components/schemas/ScalingPolicy' delete: tags: - Scaling summary: Delete scaling policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Policy deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /scaling/services: get: tags: - Scaling summary: List service scaling states security: - bearerAuth: [] responses: '200': description: Per-service scaling state (replicas, last scale, cooldowns) content: application/json: schema: type: object properties: services: type: array items: type: object /scaling/services/{serviceId}: get: tags: - Scaling summary: Get service scaling state security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Scaling state for one service content: application/json: schema: type: object /scaling/services/{serviceId}/history: get: tags: - Scaling summary: Scaling history security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Scaling events for the service content: application/json: schema: type: object properties: history: type: array items: $ref: '#/components/schemas/ScalingEvent' /scaling/services/{serviceId}/scale: post: tags: - Scaling summary: Manual scale description: Immediately scale a service to a replica count. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' requestBody: required: true content: application/json: schema: type: object required: - replicas properties: replicas: type: integer minimum: 1 maximum: 20 reason: type: string responses: '200': description: Scale event recorded content: application/json: schema: $ref: '#/components/schemas/ScalingEvent' '400': description: Invalid replica count or cooldown active content: application/json: schema: $ref: '#/components/schemas/Error' /scaling/status: get: tags: - Scaling summary: Autoscaler status security: - bearerAuth: [] responses: '200': description: Whether the autoscaler is enabled plus counts content: application/json: schema: type: object /scaling/enable: post: tags: - Scaling summary: Enable autoscaler security: - bearerAuth: [] responses: '200': description: Autoscaler enabled content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /scaling/disable: post: tags: - Scaling summary: Disable autoscaler security: - bearerAuth: [] responses: '200': description: Autoscaler disabled content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /scaling/metrics: get: tags: - Scaling summary: Scaling engine metrics security: - bearerAuth: [] responses: '200': description: Internal autoscaler metrics content: application/json: schema: type: object /scaling/events: get: tags: - Scaling summary: Recent scaling events security: - bearerAuth: [] responses: '200': description: All recent scale up/down events content: application/json: schema: type: object properties: events: type: array items: $ref: '#/components/schemas/ScalingEvent' # High availability /ha/status: get: tags: - HA summary: HA status security: - bearerAuth: [] responses: '200': description: Overall HA status (enabled, policies, active alerts) content: application/json: schema: type: object /ha/enable: post: tags: - HA summary: Enable HA management security: - bearerAuth: [] responses: '200': description: HA enabled content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/disable: post: tags: - HA summary: Disable HA management security: - bearerAuth: [] responses: '200': description: HA disabled content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/failover: post: tags: - HA summary: Trigger failover description: Manually trigger a failover evaluation across services with failover policies. security: - bearerAuth: [] requestBody: content: application/json: schema: type: object properties: reason: type: string responses: '200': description: Failover triggered content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/failover/policies: get: tags: - HA summary: List failover policies security: - bearerAuth: [] responses: '200': description: All failover policies content: application/json: schema: type: object properties: policies: type: array items: $ref: '#/components/schemas/FailoverPolicy' post: tags: - HA summary: Create or replace failover policy security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FailoverPolicy' responses: '201': description: Policy stored content: application/json: schema: type: object properties: policy: $ref: '#/components/schemas/FailoverPolicy' /ha/failover/policies/{serviceId}: get: tags: - HA summary: Get failover policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Failover policy content: application/json: schema: type: object properties: policy: $ref: '#/components/schemas/FailoverPolicy' '404': description: Policy not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - HA summary: Update failover policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FailoverPolicy' responses: '200': description: Policy updated content: application/json: schema: type: object properties: policy: $ref: '#/components/schemas/FailoverPolicy' delete: tags: - HA summary: Delete failover policy security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ServiceIdParam' responses: '200': description: Policy deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/health/checks: get: tags: - HA summary: List health checks security: - bearerAuth: [] responses: '200': description: Configured health checks content: application/json: schema: type: object properties: checks: type: array items: $ref: '#/components/schemas/HealthCheck' post: tags: - HA summary: Add health check security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/HealthCheck' responses: '201': description: Health check created content: application/json: schema: type: object properties: check: $ref: '#/components/schemas/HealthCheck' /ha/health/checks/{checkId}: get: tags: - HA summary: Get health check security: - bearerAuth: [] parameters: - name: checkId in: path required: true schema: type: string responses: '200': description: Health check content: application/json: schema: type: object properties: check: $ref: '#/components/schemas/HealthCheck' '404': description: Check not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - HA summary: Update health check security: - bearerAuth: [] parameters: - name: checkId in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/HealthCheck' responses: '200': description: Health check updated content: application/json: schema: type: object properties: check: $ref: '#/components/schemas/HealthCheck' delete: tags: - HA summary: Delete health check security: - bearerAuth: [] parameters: - name: checkId in: path required: true schema: type: string responses: '200': description: Health check deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/health/results: get: tags: - HA summary: Health check results security: - bearerAuth: [] responses: '200': description: Latest result per health check content: application/json: schema: type: object /ha/alerts/rules: get: tags: - HA summary: List alert rules security: - bearerAuth: [] responses: '200': description: All alert rules content: application/json: schema: type: object properties: rules: type: array items: $ref: '#/components/schemas/AlertRule' post: tags: - HA summary: Add alert rule security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertRule' responses: '201': description: Alert rule created content: application/json: schema: type: object properties: rule: $ref: '#/components/schemas/AlertRule' /ha/alerts/rules/{ruleId}: get: tags: - HA summary: Get alert rule security: - bearerAuth: [] parameters: - name: ruleId in: path required: true schema: type: string responses: '200': description: Alert rule content: application/json: schema: type: object properties: rule: $ref: '#/components/schemas/AlertRule' '404': description: Rule not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - HA summary: Update alert rule security: - bearerAuth: [] parameters: - name: ruleId in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertRule' responses: '200': description: Alert rule updated content: application/json: schema: type: object properties: rule: $ref: '#/components/schemas/AlertRule' delete: tags: - HA summary: Delete alert rule security: - bearerAuth: [] parameters: - name: ruleId in: path required: true schema: type: string responses: '200': description: Alert rule deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/alerts/active: get: tags: - HA summary: Active alerts security: - bearerAuth: [] responses: '200': description: Currently firing alerts content: application/json: schema: type: object properties: alerts: type: array items: type: object /ha/alerts/{alertId}/resolve: post: tags: - HA summary: Resolve alert security: - bearerAuth: [] parameters: - name: alertId in: path required: true schema: type: string responses: '200': description: Alert resolved content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /ha/notifiers: get: tags: - HA summary: List notifiers security: - bearerAuth: [] responses: '200': description: Configured alert notifiers content: application/json: schema: type: object properties: notifiers: type: array items: $ref: '#/components/schemas/Notifier' post: tags: - HA summary: Add notifier security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/NotifierRequest' responses: '201': description: Notifier created content: application/json: schema: type: object properties: notifier: $ref: '#/components/schemas/Notifier' /ha/notifiers/{notifierId}: get: tags: - HA summary: Get notifier security: - bearerAuth: [] parameters: - name: notifierId in: path required: true schema: type: string responses: '200': description: Notifier content: application/json: schema: type: object properties: notifier: $ref: '#/components/schemas/Notifier' '404': description: Notifier not found content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - HA summary: Delete notifier security: - bearerAuth: [] parameters: - name: notifierId in: path required: true schema: type: string responses: '200': description: Notifier deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' # Node agents — management (JWT-authenticated) /agents: get: tags: - Agents summary: List node agents security: - bearerAuth: [] responses: '200': description: All registered node agents content: application/json: schema: type: object properties: agents: type: array items: $ref: '#/components/schemas/NodeAgent' /agents/{id}: get: tags: - Agents summary: Get node agent security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' responses: '200': description: Agent detail content: application/json: schema: type: object properties: agent: $ref: '#/components/schemas/NodeAgent' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Agents summary: Update node agent description: Partial update — accepts any subset of agent fields (name, status, labels, etc.). security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' requestBody: required: true content: application/json: schema: type: object description: Subset of NodeAgent fields to update responses: '200': description: Agent updated content: application/json: schema: type: object properties: agent: $ref: '#/components/schemas/NodeAgent' delete: tags: - Agents summary: Deregister node agent security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' responses: '200': description: Agent removed content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /agents/{id}/containers: get: tags: - Agents summary: List agent containers security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' responses: '200': description: Containers running on the agent content: application/json: schema: type: object properties: containers: type: array items: $ref: '#/components/schemas/ContainerInstance' post: tags: - Agents summary: Create container on agent security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateContainerRequest' responses: '201': description: Container created content: application/json: schema: type: object properties: container: $ref: '#/components/schemas/ContainerInstance' '404': description: Agent not found content: application/json: schema: $ref: '#/components/schemas/Error' /agents/{id}/containers/{containerId}/start: post: tags: - Agents summary: Start container security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' - $ref: '#/components/parameters/ContainerIdParam' responses: '200': description: Container start dispatched content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /agents/{id}/containers/{containerId}/stop: post: tags: - Agents summary: Stop container security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' - $ref: '#/components/parameters/ContainerIdParam' responses: '200': description: Container stop dispatched content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /agents/{id}/containers/{containerId}/restart: post: tags: - Agents summary: Restart container security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' - $ref: '#/components/parameters/ContainerIdParam' responses: '200': description: Container restart dispatched content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /agents/{id}/containers/{containerId}: delete: tags: - Agents summary: Remove container security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' - $ref: '#/components/parameters/ContainerIdParam' responses: '200': description: Container removal dispatched content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /agents/{id}/metrics: get: tags: - Agents summary: Agent metrics description: Resource telemetry reported by the node agent. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' responses: '200': description: Agent metrics and heartbeat history content: application/json: schema: type: object /agents/{id}/commands: get: tags: - Agents summary: List agent commands security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' responses: '200': description: Command history for the agent content: application/json: schema: type: object properties: commands: type: array items: $ref: '#/components/schemas/AgentCommand' post: tags: - Agents summary: Execute command on agent description: Queue a command for the agent to pick up on its next poll. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExecuteCommandRequest' responses: '201': description: Command queued content: application/json: schema: type: object properties: command: $ref: '#/components/schemas/AgentCommand' /agents/{id}/commands/{commandId}: get: tags: - Agents summary: Get command status security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/AgentIdParam' - name: commandId in: path required: true schema: type: string responses: '200': description: Command status and result content: application/json: schema: type: object properties: command: $ref: '#/components/schemas/AgentCommand' '404': description: Command not found content: application/json: schema: $ref: '#/components/schemas/Error' # Node agents — ingestion (token-authenticated, served under /api not /api/v1) /api/agents/register: servers: - url: http://localhost:8080 post: tags: - Agents summary: Register node agent description: Agent self-registration. Requires the agent auth token (body or X-Agent-Token header). requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RegisterAgentRequest' responses: '201': description: Agent registered content: application/json: schema: type: object properties: agent: $ref: '#/components/schemas/NodeAgent' '401': description: Invalid auth token content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/heartbeat: servers: - url: http://localhost:8080 post: tags: - Agents summary: Agent heartbeat description: Periodic heartbeat carrying resource usage and container counts. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AgentHeartbeat' responses: '200': description: Heartbeat recorded content: application/json: schema: $ref: '#/components/schemas/MessageResponse' '401': description: Invalid auth token content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{id}/commands: servers: - url: http://localhost:8080 get: tags: - Agents summary: Poll pending commands description: Agent pulls its pending command queue. parameters: - name: id in: path required: true schema: type: string responses: '200': description: Pending commands content: application/json: schema: type: object properties: commands: type: array items: $ref: '#/components/schemas/AgentCommand' /api/git/webhooks/{id}: servers: - url: http://localhost:8080 post: tags: - Git summary: Push event receiver description: >- Public provider webhook endpoint. The HMAC signature against the stored webhook secret replaces session auth: GitHub X-Hub-Signature-256, Gitea X-Gitea-Signature, GitLab X-Gitlab-Token. Matching branch pushes enqueue deployments for connected services. parameters: - name: id in: path required: true schema: type: string format: uuid requestBody: required: true content: application/json: schema: type: object description: Provider push payload (ref, repository, head_commit) responses: '202': description: Push accepted; matched services queued for deployment content: application/json: schema: type: object properties: received: type: boolean branch: type: string deployments: type: integer ignored: type: string '400': description: Invalid webhook ID or payload content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Invalid signature content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Webhook disabled content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Webhook or repository not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/agents/{id}/commands/{commandId}/result: servers: - url: http://localhost:8080 post: tags: - Agents summary: Report command result parameters: - name: id in: path required: true schema: type: string - name: commandId in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object required: - status properties: status: type: string enum: [completed, failed] result: type: string error: type: string responses: '200': description: Result recorded content: application/json: schema: $ref: '#/components/schemas/MessageResponse' '401': description: Invalid auth token content: application/json: schema: $ref: '#/components/schemas/Error' # Preview environments /projects/{id}/preview-environments: get: tags: - Preview Environments summary: List preview environments security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' responses: '200': description: Preview environments for the project content: application/json: schema: type: object properties: preview_environments: type: array items: $ref: '#/components/schemas/PreviewEnvironment' post: tags: - Preview Environments summary: Create preview environment description: Spin up a preview deployment for a branch or PR. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreatePreviewEnvironmentRequest' responses: '201': description: Preview environment created content: application/json: schema: $ref: '#/components/schemas/PreviewEnvironment' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /preview-environments/{id}: get: tags: - Preview Environments summary: Get preview environment security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Preview environment content: application/json: schema: $ref: '#/components/schemas/PreviewEnvironment' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Preview Environments summary: Update preview environment security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdatePreviewEnvironmentRequest' responses: '200': description: Preview environment updated content: application/json: schema: $ref: '#/components/schemas/PreviewEnvironment' delete: tags: - Preview Environments summary: Delete preview environment security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Preview environment deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /preview-environments/{id}/promote: post: tags: - Preview Environments summary: Promote preview to production security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PromotePreviewEnvironmentRequest' responses: '200': description: Preview promoted; returns the target deployment content: application/json: schema: type: object /preview-environments/cleanup-expired: post: tags: - Preview Environments summary: Cleanup expired previews description: Tear down preview environments past their TTL. Normally run by the scheduler; exposed for manual runs. security: - bearerAuth: [] responses: '200': description: Cleanup completed content: application/json: schema: type: object properties: cleaned: type: integer # Security /security/scans: post: tags: - Security summary: Start security scan security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StartSecurityScanRequest' responses: '201': description: Scan started content: application/json: schema: $ref: '#/components/schemas/SecurityScan' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /security/scans/{id}: get: tags: - Security summary: Get security scan security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Scan status and results content: application/json: schema: $ref: '#/components/schemas/SecurityScan' '404': description: Scan not found content: application/json: schema: $ref: '#/components/schemas/Error' /projects/{id}/security/history: get: tags: - Security summary: Project scan history security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' responses: '200': description: Security scans for the project content: application/json: schema: type: object properties: scans: type: array items: $ref: '#/components/schemas/SecurityScan' /projects/{id}/vulnerabilities: get: tags: - Security summary: Project vulnerabilities security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' responses: '200': description: Vulnerability findings for the project content: application/json: schema: type: object properties: vulnerabilities: type: array items: $ref: '#/components/schemas/Vulnerability' /vulnerabilities/{id}: put: tags: - Security summary: Update vulnerability description: Mark a finding open/resolved/ignored with optional notes. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object required: - status properties: status: type: string enum: [open, resolved, ignored] notes: type: string responses: '200': description: Vulnerability updated content: application/json: schema: type: object properties: status: type: string /security/compliance/assess: post: tags: - Security summary: Start compliance assessment security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/StartComplianceAssessmentRequest' responses: '201': description: Assessment started content: application/json: schema: type: object '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /security/compliance/reports/{id}: get: tags: - Security summary: Get compliance report security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Compliance report with per-control results content: application/json: schema: type: object '404': description: Report not found content: application/json: schema: $ref: '#/components/schemas/Error' /security/compliance/frameworks: get: tags: - Security summary: List compliance frameworks security: - bearerAuth: [] responses: '200': description: Available compliance frameworks (SOC2, GDPR, ...) content: application/json: schema: type: object properties: frameworks: type: array items: type: object /security/compliance/gdpr/init: post: tags: - Security summary: Initialize GDPR framework description: Seed the GDPR control set for compliance assessments. security: - bearerAuth: [] responses: '200': description: GDPR framework initialized content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /projects/{id}/security/metrics: get: tags: - Security summary: Project security metrics description: 'Aggregate score: open findings by severity, latest scan, compliance status.' security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' responses: '200': description: Security metrics content: application/json: schema: type: object /projects/{id}/security/audit-logs: get: tags: - Security summary: Security audit logs description: Audit events scoped to a project (security-relevant actions). security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/ProjectIdParam' responses: '200': description: Audit events content: application/json: schema: type: object properties: audit_logs: type: array items: $ref: '#/components/schemas/AuditLog' # Cron jobs /cron-jobs: get: tags: - Cron summary: List cron jobs parameters: - name: project_id in: query schema: type: string format: uuid - name: service_id in: query schema: type: string format: uuid security: - bearerAuth: [] responses: '200': description: Cron jobs content: application/json: schema: type: object properties: cron_jobs: type: array items: $ref: '#/components/schemas/CronJob' post: tags: - Cron summary: Create cron job security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCronJobRequest' responses: '201': description: Cron job created content: application/json: schema: $ref: '#/components/schemas/CronJob' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' /cron-jobs/{id}: get: tags: - Cron summary: Get cron job security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Cron job content: application/json: schema: $ref: '#/components/schemas/CronJob' '404': description: Not found content: application/json: schema: $ref: '#/components/schemas/Error' put: tags: - Cron summary: Update cron job security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateCronJobRequest' responses: '200': description: Cron job updated content: application/json: schema: $ref: '#/components/schemas/CronJob' delete: tags: - Cron summary: Delete cron job security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Cron job deleted content: application/json: schema: $ref: '#/components/schemas/MessageResponse' /cron-jobs/{id}/executions: get: tags: - Cron summary: Cron execution history security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Executions for the cron job content: application/json: schema: type: object properties: executions: type: array items: $ref: '#/components/schemas/CronExecution' /cron-jobs/{id}/trigger: post: tags: - Cron summary: Trigger cron job now security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Execution started content: application/json: schema: $ref: '#/components/schemas/CronExecution' # API Gateway (merged APwhy management surface) /gateway/services: get: tags: - Gateway summary: List gateway services description: Upstream services registered for key-gated proxying. security: - bearerAuth: [] responses: '200': description: Gateway services content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' post: tags: - Gateway summary: Register gateway service security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GatewayServiceRequest' responses: '201': description: Service registered content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' '400': description: Invalid input content: application/json: schema: $ref: '#/components/schemas/Error' '409': description: Name or route prefix already registered content: application/json: schema: $ref: '#/components/schemas/Error' /gateway/services/{id}: patch: tags: - Gateway summary: Enable/disable gateway service security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean responses: '200': description: Service updated content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' /gateway/services/{id}/validate: get: tags: - Gateway summary: Validate upstream reachability description: Probes the service's upstream health path and records the result. security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' responses: '200': description: Validation result (reachable flag + status) content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' /gateway/keys: get: tags: - Gateway summary: List API keys security: - bearerAuth: [] responses: '200': description: API keys (hashes never returned) content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' post: tags: - Gateway summary: Issue API key description: The plaintext key is returned exactly once in this response. security: - bearerAuth: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/GatewayAPIKeyRequest' responses: '201': description: Key issued — `key` field holds the plaintext token content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' '400': description: Invalid input or unknown plan content: application/json: schema: $ref: '#/components/schemas/Error' /gateway/keys/{id}: patch: tags: - Gateway summary: Enable/disable API key security: - bearerAuth: [] parameters: - $ref: '#/components/parameters/IdParam' requestBody: required: true content: application/json: schema: type: object properties: enabled: type: boolean responses: '200': description: Key updated content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' /gateway/analytics/ops: get: tags: - Gateway summary: Operations analytics description: Error rates, incident counts, and uptime per gateway service. security: - bearerAuth: [] responses: '200': description: Ops analytics content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' /gateway/analytics/traffic: get: tags: - Gateway summary: Traffic analytics description: Request volume timeseries per gateway service. security: - bearerAuth: [] responses: '200': description: Traffic analytics content: application/json: schema: $ref: '#/components/schemas/GatewayResponse' components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT schemas: Error: type: object properties: error: type: string description: Error message code: type: string description: Error code details: type: object description: Additional error details HealthResponse: type: object properties: status: type: string example: ok service: type: string example: containr-api version: type: string example: 1.0.0 LoginRequest: type: object required: - email - password properties: email: type: string format: email description: User email address password: type: string format: password description: User password LoginResponse: type: object properties: token: type: string description: JWT access token user: $ref: '#/components/schemas/User' RegisterRequest: type: object required: - email - password - name properties: email: type: string format: email description: User email address password: type: string format: password description: User password name: type: string description: User display name PlatformSettings: type: object properties: signup_enabled: type: boolean description: Whether public account registration is open after bootstrap cloudflare_tunnel: type: object properties: token_set: type: boolean description: Whether a tunnel token is configured (value is never returned) source: type: string enum: [app, env, none] description: Where the active token comes from - in-app setting, env fallback, or unset container: type: string description: cloudflared container state - running/exited/missing, or unavailable when Docker is unreachable User: type: object properties: id: type: string description: User ID email: type: string format: email description: User email name: type: string description: User display name avatar_url: type: string description: Optional avatar image URL is_admin: type: boolean description: True for the platform owner (first registered account) created_at: type: string format: date-time description: Account creation timestamp updated_at: type: string format: date-time description: Last update timestamp UpdateUserRequest: type: object properties: name: type: string description: User display name email: type: string format: email description: User email address avatar_url: type: string description: Optional avatar image URL Project: type: object properties: id: type: string description: Project ID name: type: string description: Project name description: type: string description: Project description owner_id: type: string description: Project owner ID created_at: type: string format: date-time description: Project creation timestamp updated_at: type: string format: date-time description: Last update timestamp stats: $ref: '#/components/schemas/ProjectStats' ProjectStats: type: object required: - service_count - deployment_count - running_services - last_deployment properties: service_count: type: integer deployment_count: type: integer running_services: type: integer last_deployment: type: string nullable: true description: Timestamp of the most recent deployment CreateProjectRequest: type: object required: - name properties: name: type: string description: Project name description: type: string description: Project description UpdateProjectRequest: type: object properties: name: type: string description: Project name description: type: string description: Project description ProjectsResponse: type: object properties: projects: type: array items: $ref: '#/components/schemas/Project' pagination: $ref: '#/components/schemas/Pagination' Pagination: type: object properties: page: type: integer description: Current page number limit: type: integer description: Items per page total: type: integer description: Total number of items total_pages: type: integer description: Total number of pages Service: type: object properties: id: type: string format: uuid description: Service ID project_id: type: string format: uuid description: Project ID name: type: string description: Service name type: type: string enum: [web, worker, database, cron] description: Service type status: type: string enum: [running, stopped, building, failed] description: Service status image: type: string description: Container image command: type: string description: Start command environment: type: string enum: [production, preview, development] description: Deployment environment git_repo: type: string description: Connected git repository git_branch: type: string description: Connected git branch build_path: type: string description: Build context path cpu: type: string description: CPU allocation memory: type: string description: Memory allocation replicas: type: integer description: Desired replica count port: type: integer description: Container port to expose (published host port, or Traefik when domain set) domain: type: string description: Public hostname routed via Traefik healthcheck_path: type: string description: HTTP path probed on port for container health restart_policy: type: string description: Docker restart policy (default unless-stopped) public_url: type: string description: Computed public URL (published port or domain) created_at: type: string format: date-time description: Service creation timestamp updated_at: type: string format: date-time description: Last update timestamp CreateServiceRequest: type: object required: - name - type - environment properties: project_id: type: string format: uuid description: Defaults to the project in the URL; must match when set name: type: string description: Service name type: type: string enum: [web, worker, database, cron] description: Service type image: type: string description: Container image command: type: string description: Start command environment: type: string enum: [production, preview, development] description: Deployment environment git_repo: type: string description: Git repository URL git_branch: type: string description: Git branch build_path: type: string description: Build context path cpu: type: string description: CPU allocation memory: type: string description: Memory allocation replicas: type: integer description: Desired replica count port: type: integer description: Container port to expose domain: type: string description: Public hostname routed via Traefik healthcheck_path: type: string description: HTTP path probed for container health restart_policy: type: string description: Docker restart policy UpdateServiceRequest: type: object properties: name: type: string description: Service name type: type: string enum: [web, worker, database, cron] description: Service type image: type: string description: Container image command: type: string description: Start command environment: type: string enum: [production, preview, development] description: Deployment environment git_repo: type: string description: Git repository URL git_branch: type: string description: Git branch build_path: type: string description: Build context path cpu: type: string description: CPU allocation memory: type: string description: Memory allocation replicas: type: integer description: Desired replica count port: type: integer description: Container port to expose domain: type: string description: Public hostname routed via Traefik healthcheck_path: type: string description: HTTP path probed for container health restart_policy: type: string description: Docker restart policy Deployment: type: object properties: id: type: string description: Deployment ID service_id: type: string description: Service ID commit_hash: type: string description: Source commit hash status: type: string description: Deployment status image_name: type: string description: Deployed image name image_tag: type: string description: Deployed image tag build_log: type: string description: Build log content runtime_log: type: string description: Runtime log content error: type: string description: Deployment error started_at: type: string format: date-time description: Deployment start timestamp completed_at: type: string format: date-time description: Deployment completion timestamp created_at: type: string format: date-time description: Deployment creation timestamp updated_at: type: string format: date-time description: Deployment update timestamp DeploymentListResponse: type: object properties: deployments: type: array items: $ref: '#/components/schemas/Deployment' CreateDeploymentRequest: type: object properties: commit_hash: type: string description: Source commit hash branch: type: string description: Source branch trigger: type: string description: Trigger source (manual, restart, webhook) env_vars: type: object additionalProperties: type: string description: Runtime environment variable overrides RollbackDeploymentResponse: type: object properties: deployment: $ref: '#/components/schemas/Deployment' message: type: string description: Rollback result message ServiceLogEntry: type: object properties: timestamp: type: string format: date-time description: Log timestamp message: type: string description: Log message stream: type: string description: Log stream identifier ServiceLogsResponse: type: object properties: logs: type: array items: $ref: '#/components/schemas/ServiceLogEntry' message: type: string description: Additional context when logs are unavailable DeploymentLogsResponse: type: object properties: logs: type: array items: $ref: '#/components/schemas/ServiceLogEntry' build_log: type: string description: Build log text runtime_log: type: string description: Runtime log text BuildStatus: type: object properties: id: type: string description: Build ID project_id: type: string description: Project ID service_id: type: string description: Service ID status: type: string enum: [pending, running, success, failed, cancelled] description: Build status progress: type: integer minimum: 0 maximum: 100 description: Build progress percentage started_at: type: string format: date-time description: Build start time completed_at: type: string format: date-time description: Build completion time image_name: type: string description: Target image name image_tag: type: string description: Target image tag size: type: integer format: int64 description: Built image size in bytes error: type: string description: Build error message log: type: string description: Build logs metadata: type: object additionalProperties: type: string description: Additional build metadata StartBuildRequest: type: object required: - image_name - image_tag properties: build_type: type: string description: Build system type; if omitted backend auto-detects enum: [railpack, nixpacks, dockerfile, prebuilt] source_path: type: string description: Local source path for build context prebuilt_image: type: string description: Existing image reference when using prebuilt mode image_name: type: string description: Output image name image_tag: type: string description: Output image tag registry_url: type: string description: Optional registry URL for push target build_command: type: string description: Optional build command override start_command: type: string description: Optional runtime command override environment: type: object additionalProperties: type: string description: Build environment variables build_args: type: object additionalProperties: type: string description: Build-time arguments labels: type: object additionalProperties: type: string description: Image labels project_id: type: string description: Associated project ID service_id: type: string description: Associated service ID branch: type: string description: Git branch commit: type: string description: Git commit SHA StartBuildResponse: type: object properties: id: type: string description: Build ID status: type: string enum: [pending, running, success, failed, cancelled] description: Initial build status image_name: type: string description: Requested image name image_tag: type: string description: Requested image tag size: type: integer format: int64 description: Result image size in bytes when available digest: type: string description: Result image digest when available build_time: type: string format: date-time description: Build request timestamp success: type: boolean description: Whether request acceptance succeeded error: type: string description: Error details when acceptance failed BuildListResponse: type: object properties: builds: type: array items: $ref: '#/components/schemas/BuildStatus' total: type: integer description: Total matching builds page: type: integer description: Current page number limit: type: integer description: Page size BuildCancelResponse: type: object properties: message: type: string description: Cancellation result message ServiceTemplate: type: object properties: id: type: string description: Template ID name: type: string description: Template display name description: type: string description: Template description category: type: string description: Template category logo: type: string description: Template logo URL config: type: string description: Raw template config JSON string variables: type: string description: Raw template variables JSON string is_official: type: boolean description: Whether template is an official preset created_at: type: string format: date-time description: Creation timestamp updated_at: type: string format: date-time description: Last update timestamp TemplateConfig: type: object properties: type: type: string description: Service type for created service runtime: type: string description: Runtime or base image build_command: type: string description: Build command start_command: type: string description: Start command port: type: integer description: Service port health_check: type: string description: Health check path environment: type: object additionalProperties: type: string description: Default environment variables dockerfile: type: string description: Optional dockerfile path nixpacks_config: type: object additionalProperties: type: string description: Optional nixpacks-specific config TemplateVariable: type: object properties: key: type: string description: Variable key label: type: string description: Display label default: type: string description: Default value required: type: boolean description: Whether variable is required secret: type: boolean description: Whether variable is sensitive description: type: string description: Variable description TemplateDetailResponse: type: object properties: template: $ref: '#/components/schemas/ServiceTemplate' config: $ref: '#/components/schemas/TemplateConfig' variables: type: array items: $ref: '#/components/schemas/TemplateVariable' DeployTemplateRequest: type: object required: - project_id - name properties: project_id: type: string description: Target project ID name: type: string description: Name for the created service plan: type: string enum: [hobby, starter, standard, business] description: Optional managed database plan for database templates region: type: string description: Optional managed database region for database templates variables: type: object additionalProperties: type: string description: Variable overrides for template deployment DeployTemplateResponse: type: object properties: resource: type: string enum: [service, database] description: Type of resource created by template deployment service_id: type: string description: Newly created service ID (set for non-database templates) database_id: type: string description: Newly created managed database ID (set for database templates) message: type: string description: Deployment result message AuditLog: type: object properties: id: type: string description: Audit log ID user_id: type: string description: User ID that triggered action user_email: type: string description: User email snapshot resource: type: string description: Resource type resource_id: type: string description: Resource ID action: type: string description: Action type details: type: string description: JSON-encoded action details ip_address: type: string description: Source IP address user_agent: type: string description: Source user agent created_at: type: string format: date-time description: Timestamp when the audit log entry was created Notification: type: object properties: id: type: string format: uuid kind: type: string title: type: string body: type: string resource_type: type: string resource_id: type: string read_at: type: string format: date-time nullable: true created_at: type: string format: date-time NotificationListResponse: type: object properties: notifications: type: array items: $ref: '#/components/schemas/Notification' unread: type: integer AuditLogListResponse: type: object properties: audit_logs: type: array items: $ref: '#/components/schemas/AuditLog' Database: type: object properties: id: type: string description: Database ID name: type: string description: Database name type: type: string enum: [postgresql, redis, mysql, mariadb, mongodb, clickhouse, dragonfly] description: Database type status: type: string enum: [running, stopped, building, error] description: Database status connection_url: type: string description: Database connection URL version: type: string description: Database version plan: type: string enum: [hobby, starter, standard, business] description: Provisioning plan region: type: string description: Provisioning region backup_schedule: type: string description: Cron expression for automatic backups, empty when unset next_backup_at: type: string format: date-time description: Next scheduled backup run metrics: $ref: '#/components/schemas/DatabaseMetrics' backups: $ref: '#/components/schemas/DatabaseBackupConfig' settings: $ref: '#/components/schemas/DatabaseSettings' created_at: type: string format: date-time description: Database creation timestamp updated_at: type: string format: date-time description: Last update timestamp CreateDatabaseRequest: type: object required: - name - type - plan - region properties: name: type: string description: Database name type: type: string enum: [postgresql, redis, mysql, mariadb, mongodb, clickhouse, dragonfly] description: Database type plan: type: string enum: [hobby, starter, standard, business] description: Database plan region: type: string description: Database region UpdateDatabaseRequest: type: object properties: name: type: string description: Updated database name plan: type: string enum: [hobby, starter, standard, business] description: Updated database plan backup_schedule: type: string nullable: true description: Cron expression for automatic backups; empty string clears the schedule DatabaseActionRequest: type: object required: - action properties: action: type: string enum: [start, stop, restart] description: Action to execute DatabaseRestoreRequest: type: object required: - backup_id properties: backup_id: type: string description: Backup identifier to restore DatabaseCreateResponse: type: object properties: id: type: string description: Database ID message: type: string status: type: string enum: [building] DatabaseActionResponse: type: object properties: message: type: string status: type: string enum: [running, stopped, building, error] DatabaseBackupCreateResponse: type: object properties: backup_id: type: string message: type: string status: type: string enum: [in_progress] DatabaseListResponse: type: object properties: databases: type: array items: $ref: '#/components/schemas/Database' DatabaseMetrics: type: object properties: cpu: type: number memory: type: number storage: type: number connections: type: integer read_iops: type: integer write_iops: type: integer network_in: type: number network_out: type: number DatabaseBackup: type: object properties: id: type: string created_at: type: string format: date-time size: type: string status: type: string enum: [completed, failed, in_progress] DatabaseBackupConfig: type: object properties: enabled: type: boolean last_backup: type: string format: date-time retention: type: integer next_backup: type: string format: date-time backups: type: array items: $ref: '#/components/schemas/DatabaseBackup' DatabaseSettings: type: object properties: max_connections: type: integer timeout: type: integer ssl: type: boolean logging: type: boolean MessageResponse: type: object properties: message: type: string GitProvider: type: object required: - id - name - display_name - api_url - webhook_url - user_id - created_at - updated_at properties: id: type: string description: Provider ID name: type: string enum: [github, gitlab, bitbucket, gitea, github_app] description: Provider type identifier display_name: type: string description: Provider display name api_url: type: string description: Custom API base URL (self-hosted providers) webhook_url: type: string description: Webhook callback URL registered on the provider user_id: type: string created_at: type: string format: date-time updated_at: type: string format: date-time description: Access tokens are never serialized in responses. CreateGitProviderRequest: type: object required: - name - display_name - access_token properties: name: type: string enum: [github, gitlab, bitbucket, gitea, github_app] description: Provider type identifier display_name: type: string description: Provider display name access_token: type: string description: Personal access token (stored encrypted, never returned) api_url: type: string description: Custom API base URL for self-hosted providers GitBranch: type: object required: - name - protected properties: name: type: string protected: type: boolean GitRepository: type: object required: - id - provider_id - name - full_name - description - clone_url - webhook_url - default_branch - is_private - user_id - created_at - updated_at properties: id: type: string description: Repository ID provider_id: type: string name: type: string description: Repository name full_name: type: string description: Repository full name (owner/repo) description: type: string description: Repository description clone_url: type: string description: Clone URL webhook_url: type: string default_branch: type: string description: Default branch is_private: type: boolean description: Whether repository is private user_id: type: string created_at: type: string format: date-time updated_at: type: string format: date-time ManualUserCreateRequest: type: object required: - email - password - name properties: email: type: string format: email password: type: string format: password minLength: 8 maxLength: 128 name: type: string minLength: 2 maxLength: 255 ServiceVariable: type: object properties: id: type: string format: uuid service_id: type: string format: uuid key: type: string value: type: string description: Masked as ******** when is_secret is true is_secret: type: boolean created_at: type: string format: date-time updated_at: type: string format: date-time VariableInput: type: object required: - key properties: key: type: string value: type: string is_secret: type: boolean UpdateVariablesRequest: type: object required: - variables properties: variables: type: array items: $ref: '#/components/schemas/VariableInput' ConnectGitHubAppRequest: type: object required: - installation_id properties: installation_id: type: integer format: int64 description: GitHub App installation ID from the install callback display_name: type: string ConnectGitRepoRequest: type: object required: - provider_id - repo_full_name properties: provider_id: type: string repo_full_name: type: string description: owner/repo CreateWebhookRequest: type: object required: - repo_id - events properties: repo_id: type: string events: type: array items: type: string example: [push, pull_request] branch: type: string GitWebhook: type: object properties: id: type: string repo_id: type: string provider_id: type: string events: type: array items: type: string description: Subscribed provider events branch: type: string description: Branch filter for push events active: type: boolean created_at: type: string format: date-time updated_at: type: string format: date-time description: Webhook secrets are never serialized in responses. BuildRequest: type: object required: - image_name - image_tag properties: build_type: type: string description: dockerfile | railpack | prebuilt — auto-detected when empty source_path: type: string prebuilt_image: type: string image_name: type: string image_tag: type: string registry_url: type: string build_command: type: string start_command: type: string environment: type: object additionalProperties: type: string build_args: type: object additionalProperties: type: string labels: type: object additionalProperties: type: string project_id: type: string service_id: type: string branch: type: string commit: type: string UpgradeStatus: type: object properties: image_ref: type: string registry: type: string docker_available: type: boolean installed: type: boolean digest: type: string size: type: integer format: int64 auth_configured: type: boolean message: type: string HostMonitoring: type: object properties: hostname: type: string os: type: string architecture: type: string cpu: type: object properties: cores: type: integer memory: type: object properties: total: type: integer format: int64 used: type: integer format: int64 available: type: integer format: int64 usage_percent: type: number storage: type: object properties: path: type: string total: type: integer format: int64 used: type: integer format: int64 available: type: integer format: int64 usage_percent: type: number load: type: object properties: load_1m: type: number load_5m: type: number load_15m: type: number uptime_seconds: type: integer format: int64 docker_available: type: boolean docker: type: object description: Docker daemon details when available properties: containers: type: integer images: type: integer driver: type: string server: type: string collected_at: type: string format: date-time ServiceInstanceMetrics: type: object required: - container_id - name - state - cpu_percent - memory_usage_bytes - memory_limit_bytes - network_rx_bytes - network_tx_bytes - started_at properties: container_id: type: string name: type: string state: type: string cpu_percent: type: number memory_usage_bytes: type: integer format: int64 memory_limit_bytes: type: integer format: int64 network_rx_bytes: type: integer format: int64 network_tx_bytes: type: integer format: int64 started_at: type: string format: date-time ServiceMetrics: type: object required: - service_id - status - instances - cpu_percent - memory_usage_bytes - memory_limit_bytes - network_rx_bytes - network_tx_bytes - collected_at properties: service_id: type: string status: type: string enum: [ok, no_containers, docker_unavailable] instances: type: array items: $ref: '#/components/schemas/ServiceInstanceMetrics' cpu_percent: type: number memory_usage_bytes: type: integer format: int64 memory_limit_bytes: type: integer format: int64 network_rx_bytes: type: integer format: int64 network_tx_bytes: type: integer format: int64 collected_at: type: string format: date-time ScalingPolicy: type: object required: - service_id - min_replicas - max_replicas properties: service_id: type: string min_replicas: type: integer minimum: 1 max_replicas: type: integer minimum: 1 target_cpu: type: number description: Target CPU utilization percent target_memory: type: number description: Target memory utilization percent scale_up_cooldown: type: integer description: Nanoseconds (Go duration serialized as integer) scale_down_cooldown: type: integer scale_up_step: type: integer scale_down_step: type: integer metrics: type: array items: type: string thresholds: type: object additionalProperties: type: number enabled: type: boolean cost_optimization: type: object ScalingEvent: type: object properties: id: type: string service_id: type: string from_replicas: type: integer to_replicas: type: integer reason: type: string trigger: type: string description: auto | manual created_at: type: string format: date-time FailoverPolicy: type: object required: - service_id properties: service_id: type: string enabled: type: boolean min_healthy_nodes: type: integer max_failures: type: integer failover_timeout: type: integer description: Nanoseconds recovery_timeout: type: integer description: Nanoseconds failover_strategy: type: string backup_nodes: type: array items: type: string health_check_config: type: object HealthCheck: type: object properties: id: type: string service_id: type: string node_id: type: string type: type: string description: http | tcp | exec config: type: object last_check: type: string format: date-time status: type: string AlertRule: type: object properties: id: type: string name: type: string description: type: string enabled: type: boolean condition: type: object description: metric, operator, threshold, duration severity: type: string enum: [info, warning, critical] labels: type: object additionalProperties: type: string annotations: type: object additionalProperties: type: string notifiers: type: array items: type: string cooldown: type: integer description: Nanoseconds Notifier: type: object properties: id: type: string type: type: string description: webhook | slack | email | discord config: type: object NotifierRequest: type: object required: - type - config properties: id: type: string type: type: string config: type: object NodeAgent: type: object properties: id: type: string name: type: string hostname: type: string ip_address: type: string port: type: integer status: type: string description: online | offline | connecting | error version: type: string capabilities: $ref: '#/components/schemas/AgentCapabilities' resources: $ref: '#/components/schemas/NodeResources' metadata: type: object additionalProperties: true last_heartbeat: type: string format: date-time created_at: type: string format: date-time updated_at: type: string format: date-time AgentAuthToken: type: object properties: id: type: string format: uuid label: type: string created_at: type: string format: date-time last_used_at: type: string format: date-time revoked: type: boolean revoked_at: type: string format: date-time required: - id - label - created_at - revoked AgentAuthTokenCreated: allOf: - $ref: '#/components/schemas/AgentAuthToken' - type: object properties: token: type: string description: Raw token value, returned exactly once at creation required: - token CreateAgentTokenRequest: type: object properties: label: type: string description: Human-readable label for the token (e.g. node name) AgentCapabilities: type: object properties: container_runtimes: type: array items: type: string supported_architectures: type: array items: type: string max_containers: type: integer storage_driver: type: string network_plugins: type: array items: type: string features: type: array items: type: string NodeResources: type: object properties: cpu: type: object properties: cores: type: integer allocation: type: number description: Allocated CPU percentage usage: type: number description: Current usage percentage memory: type: object properties: total: type: integer format: int64 allocated: type: integer format: int64 used: type: integer format: int64 available: type: integer format: int64 storage: type: object properties: total: type: integer format: int64 allocated: type: integer format: int64 used: type: integer format: int64 available: type: integer format: int64 network: type: object properties: interfaces: type: array items: type: object properties: name: type: string ip_address: type: string mac_address: type: string speed: type: integer status: type: string bandwidth: type: object properties: inbound: type: integer format: int64 description: Bytes per second outbound: type: integer format: int64 description: Bytes per second RegisterAgentRequest: type: object required: - name - hostname - ip_address - port - capabilities properties: name: type: string hostname: type: string ip_address: type: string port: type: integer capabilities: $ref: '#/components/schemas/AgentCapabilities' auth_token: type: string description: May also be sent via the X-Agent-Token header AgentHeartbeat: type: object properties: agent_id: type: string status: type: string resources: $ref: '#/components/schemas/NodeResources' container_count: type: integer system_load: type: object uptime: type: integer version: type: string AgentCommand: type: object properties: id: type: string node_agent_id: type: string type: type: string payload: type: object status: type: string description: pending | running | completed | failed result: type: string error: type: string created_at: type: string format: date-time completed_at: type: string format: date-time ExecuteCommandRequest: type: object required: - type properties: type: type: string payload: type: object ContainerInstance: type: object properties: id: type: string agent_id: type: string project_id: type: string service_id: type: string name: type: string image: type: string status: type: string resources: type: object ports: type: array items: type: object created_at: type: string format: date-time CreateContainerRequest: type: object required: - name - image - project_id - service_id - resources properties: name: type: string image: type: string project_id: type: string service_id: type: string resources: type: object description: cpu/memory limits ports: type: array items: type: object properties: host_port: type: integer container_port: type: integer protocol: type: string environment: type: object additionalProperties: type: string volumes: type: array items: type: object networks: type: array items: type: string restart_policy: type: object health_check: type: object PreviewEnvironment: type: object properties: id: type: string format: uuid project_id: type: string format: uuid service_id: type: string format: uuid branch_name: type: string pr_number: type: integer environment: type: string description: Generated name, e.g. preview-{branch}-{ts} status: type: string enum: [building, running, failed, stopped, expired] url: type: string expires_at: type: string format: date-time deployment_id: type: string format: uuid created_at: type: string format: date-time updated_at: type: string format: date-time CreatePreviewEnvironmentRequest: type: object required: - service_id - branch_name properties: project_id: type: string format: uuid service_id: type: string format: uuid branch_name: type: string pr_number: type: integer ttl_hours: type: integer minimum: 1 maximum: 168 UpdatePreviewEnvironmentRequest: type: object properties: status: type: string enum: [building, running, failed, stopped, expired] url: type: string expires_at: type: string format: date-time ttl_hours: type: integer minimum: 1 maximum: 168 PromotePreviewEnvironmentRequest: type: object required: - target_environment properties: target_environment: type: string enum: [production, development] create_backup: type: boolean StartSecurityScanRequest: type: object required: - project_id - scan_type properties: project_id: type: string service_id: type: string scan_type: type: string enum: [dependency, configuration, comprehensive] SecurityScan: type: object properties: id: type: string project_id: type: string service_id: type: string scan_type: type: string status: type: string description: pending | running | completed | failed findings_count: type: integer started_at: type: string format: date-time completed_at: type: string format: date-time Vulnerability: type: object properties: id: type: string type: type: string severity: type: string enum: [low, medium, high, critical] title: type: string description: type: string service_id: type: string project_id: type: string status: type: string enum: [open, resolved, ignored] found_at: type: string format: date-time resolved_at: type: string format: date-time StartComplianceAssessmentRequest: type: object required: - project_id - framework_id properties: project_id: type: string framework_id: type: string CronJob: type: object properties: id: type: string project_id: type: string service_id: type: string name: type: string schedule: type: string description: Cron expression command: type: string timezone: type: string enabled: type: boolean last_run_at: type: string format: date-time next_run_at: type: string format: date-time last_status: type: string last_output: type: string retention: type: integer created_at: type: string format: date-time updated_at: type: string format: date-time CronExecution: type: object properties: id: type: string cron_job_id: type: string started_at: type: string format: date-time finished_at: type: string format: date-time status: type: string output: type: string error: type: string CreateCronJobRequest: type: object required: - project_id - service_id - name - schedule - command properties: project_id: type: string service_id: type: string name: type: string schedule: type: string command: type: string timezone: type: string enabled: type: boolean retention: type: integer UpdateCronJobRequest: type: object properties: name: type: string schedule: type: string command: type: string timezone: type: string enabled: type: boolean retention: type: integer GatewayService: type: object properties: id: type: string format: uuid name: type: string upstream_url: type: string route_prefix: type: string enabled: type: boolean rpm_limit: type: integer monthly_quota: type: integer health_path: type: string last_validated_at: type: string format: date-time last_validation_status: type: string created_at: type: string format: date-time GatewayServiceRequest: type: object required: - name - upstreamUrl - routePrefix properties: name: type: string maxLength: 100 upstreamUrl: type: string format: uri maxLength: 500 routePrefix: type: string maxLength: 200 enabled: type: boolean rpmLimit: type: integer minimum: 1 maximum: 10000 monthlyQuota: type: integer minimum: 1 maximum: 10000000 GatewayAPIKeyRequest: type: object required: - name properties: name: type: string maxLength: 100 plan: type: string enum: [free, pro, business, enterprise] default: free enabled: type: boolean rpmLimit: type: integer minimum: 1 maximum: 10000 monthlyQuota: type: integer minimum: 1 maximum: 10000000 GatewayAPIKey: type: object properties: id: type: string format: uuid name: type: string plan: type: string enabled: type: boolean rpm_limit: type: integer monthly_quota: type: integer key_prefix: type: string created_at: type: string format: date-time GatewayResponse: type: object description: Standard gateway management envelope — `data` carries the payload, `error` carries {code, message, details}, `meta` carries pagination. properties: success: type: boolean data: description: Endpoint-specific payload (GatewayService, GatewayAPIKey, arrays, or analytics objects) error: type: object properties: code: type: string message: type: string details: {} meta: type: object properties: page: type: integer per_page: type: integer total: type: integer total_pages: type: integer parameters: IdParam: name: id in: path required: true description: Resource ID schema: type: string ProjectIdParam: name: id in: path required: true description: Project ID schema: type: string ServiceIdParam: name: serviceId in: path required: true description: Service ID schema: type: string AgentIdParam: name: id in: path required: true description: Node agent ID schema: type: string ContainerIdParam: name: containerId in: path required: true description: Container ID schema: type: string tags: - name: Health description: Health check endpoints - name: Authentication description: User authentication and authorization - name: User description: User profile management - name: Projects description: Project management - name: Services description: Service management - name: Deployments description: Deployment lifecycle management - name: Logs description: Service and deployment log retrieval - name: Builds description: Build management - name: Templates description: Service template catalog and deployment - name: Audit description: Audit event history and resource-level trails - name: Notifications description: Persistent user notifications with read state - name: Databases description: Database management - name: Git description: Git integration - name: System description: System upgrade and host monitoring - name: Realtime description: WebSocket event stream - name: Agents description: Node agent management and agent ingestion - name: Scaling description: Autoscaling policies and controls - name: HA description: High availability, failover, health checks, alerts - name: Preview Environments description: Per-branch/PR preview deployments - name: Security description: Vulnerability scans and compliance reporting - name: Cron description: Scheduled jobs - name: Gateway description: API gateway — upstream services, keys, analytics