Files
Containr/docs/api/openapi.yaml
T
2026-10-09 05:12:37 +02:00

8713 lines
226 KiB
YAML

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 accepts three credentials in the Authorization header:
`Authorization: Bearer <jwt>` (UI sessions), a Better Auth session cookie, or a
personal access token `cnp_...` (CLI/MCP/agents). PAT scopes: `read` allows only
GET/HEAD/OPTIONS; `write` everything except admin routes; `admin` requires a
platform-admin owner.
## Errors
Error responses use `{"error": "human message", "code": "MACHINE_CODE"}`. Stable
codes: `UNAUTHENTICATED`, `INVALID_TOKEN`, `FORBIDDEN`, `ADMIN_REQUIRED`,
`SCOPE_INSUFFICIENT`, `NOT_FOUND`, `VALIDATION`, `CONFLICT`, `INTERNAL`,
`DEPENDENCY_UNAVAILABLE`, `IDEMPOTENCY_IN_PROGRESS`.
## Idempotency
POST endpoints accept an `Idempotency-Key` header. The first response is replayed
for repeated keys within 24h (scoped to the caller and path); a concurrent duplicate
receives `409 IDEMPOTENCY_IN_PROGRESS`. Safe for clients to always send a UUID.
## Pagination
List endpoints accept `?limit=` plus either `?page=` (legacy) or `?cursor=`
(preferred — pass `pagination.next_cursor` from the previous response verbatim).
Invalid cursors fail soft to the first page.
## 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'
/user/tokens:
get:
tags:
- User
summary: List personal access tokens
description: Returns the caller's non-revoked personal access token metadata. Token values and hashes are never returned.
security:
- bearerAuth: []
responses:
'200':
description: Token list
content:
application/json:
schema:
type: object
properties:
tokens:
type: array
items:
$ref: '#/components/schemas/UserToken'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
tags:
- User
summary: Create personal access token
description: Issues a `cnp_` bearer token for CLI/MCP/agent authentication. The raw token is returned exactly once and never stored — only its SHA-256 hash persists. Admin-scope tokens require a platform admin account.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserTokenRequest'
responses:
'201':
description: Token created; raw value returned once
content:
application/json:
schema:
$ref: '#/components/schemas/UserTokenCreated'
'400':
description: Invalid input
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Admin scope requires platform admin
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/user/tokens/{id}:
delete:
tags:
- User
summary: Revoke personal access token
description: Marks one of the caller's tokens as revoked. Clients 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:
message:
type: string
'404':
description: Token not found
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 (legacy — prefer cursor)
schema:
type: integer
default: 1
- name: limit
in: query
description: Number of items per page
schema:
type: integer
default: 20
- name: cursor
in: query
description: Opaque cursor from a previous response's pagination.next_cursor
schema:
type: string
- 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
description: Reachable service URLs; rewritten to the request Host for remote clients. Null/empty when nothing is published.
ports:
type: array
items:
type: integer
description: Host ports actually bound for replica 0+; persisted on the service so restarts reuse the same public port. Null/empty when nothing is published.
health:
type: string
enum: [healthy, unhealthy, unreachable]
description: Result of the backend's HTTP probe of the service on its project network. Omitted when the service declares no healthcheck path.
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}/sleep:
post:
tags:
- Services
summary: Sleep service
description: Scale the service to zero immediately. When it has public domains a wake placeholder holds the route and resumes the service on the next request.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'202':
description: Sleep initiated
/services/{id}/wake:
post:
tags:
- Services
summary: Wake service
description: Reconcile a sleeping service back to running on demand
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'202':
description: Wake initiated
/internal/wake/{id}:
get:
tags:
- Services
summary: Wake callback (internal)
description: Unauthenticated wake endpoint hit by the busybox wake placeholder while a slept service resumes. Idempotent and non-destructive.
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'202':
description: Wake accepted
'404':
description: Service not found
/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}/clone:
post:
tags:
- Services
summary: Clone service
description: Duplicates config, volumes, domains, access gates, builder settings, and variables into the same or another project. Containers are not cloned — the copy starts stopped.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
name:
type: string
description: Name for the clone (default "<name>-copy")
project_id:
type: string
format: uuid
description: Target project (default same project; caller must own it)
environment:
type: string
enum: [production, preview, development]
responses:
'201':
description: Clone created
content:
application/json:
schema:
type: object
properties:
service_id:
type: string
format: uuid
name:
type: string
message:
type: string
'409':
description: Name already exists in target project
/services/{id}/move:
post:
tags:
- Services
summary: Move service
description: Re-parents the service to another project the caller owns. Variables, domains, and volumes follow the service; running containers keep running and join the new project's network on next deploy.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [project_id]
properties:
project_id:
type: string
format: uuid
responses:
'200':
description: Service moved
'409':
description: Name conflict in target project
/registries:
get:
tags:
- Registries
summary: List registry credentials
description: Private-image pull credentials for the caller. Passwords are never returned — `has_password` signals presence.
security:
- bearerAuth: []
responses:
'200':
description: Registry list
content:
application/json:
schema:
type: object
properties:
registries:
type: array
items:
$ref: '#/components/schemas/Registry'
post:
tags:
- Registries
summary: Add registry credential
description: Credentials are matched by image host (e.g. ghcr.io, registry.example.com, docker.io for Docker Hub) on prebuilt-image deploys. Password stored encrypted at rest.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistryRequest'
responses:
'201':
description: Registry created
'409':
description: A registry for this host already exists
/registries/{id}:
put:
tags:
- Registries
summary: Update registry credential
description: Empty password keeps the stored credential — delete and recreate to remove a password.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistryRequest'
responses:
'200':
description: Registry updated
'404':
description: Registry not found
delete:
tags:
- Registries
summary: Remove registry credential
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Registry removed
'404':
description: Registry not found
/backup-targets:
get:
tags:
- BackupTargets
summary: List backup targets
description: S3-compatible archive destinations for the caller. Secret keys are never returned — `has_credentials` signals presence.
security:
- bearerAuth: []
responses:
'200':
description: Backup target list
content:
application/json:
schema:
type: object
properties:
backup_targets:
type: array
items:
$ref: '#/components/schemas/BackupTarget'
post:
tags:
- BackupTargets
summary: Register a backup target
description: The bucket is probed (BucketExists) before storing — typos and bad credentials fail at registration. Keys are stored encrypted at rest.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BackupTargetRequest'
responses:
'201':
description: Backup target created
'400':
description: Validation error or connection check failed
/backup-targets/{id}:
put:
tags:
- BackupTargets
summary: Update a backup target
description: Empty access_key/secret_key keep the stored pair — delete and recreate to remove credentials. Re-probed before saving.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BackupTargetRequest'
responses:
'200':
description: Backup target updated
'404':
description: Backup target not found
delete:
tags:
- BackupTargets
summary: Delete a backup target
description: Fails with 409 while databases still point at the target.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Backup target deleted
'409':
description: Databases still reference this target
/backup-targets/{id}/test:
post:
tags:
- BackupTargets
summary: Re-probe a backup target
description: Checks bucket access with the stored credentials. Always returns a probe result — `ok` false means unreachable or unauthorized.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Probe result
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
latency_ms:
type: integer
error:
type: string
/services/{id}/domains:
get:
tags:
- Services
summary: List service domains
description: All hostnames attached to the service; the default is mirrored to services.domain
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Domain list
content:
application/json:
schema:
type: object
properties:
domains:
type: array
items:
$ref: '#/components/schemas/ServiceDomain'
post:
tags:
- Services
summary: Attach a domain
description: Adds a hostname routed to the service via Traefik. The first domain becomes default automatically.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- domain
properties:
domain:
type: string
is_default:
type: boolean
responses:
'201':
description: Domain attached
content:
application/json:
schema:
type: object
properties:
domain:
$ref: '#/components/schemas/ServiceDomain'
'409':
description: Domain already attached
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/services/{id}/domains/check:
get:
tags:
- Services
summary: DNS preflight
description: Resolves every attached domain and compares it to the expected target (app_settings.public_ip / PUBLIC_IP, or base_url host)
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Per-domain DNS status
content:
application/json:
schema:
type: object
properties:
domains:
type: array
items:
$ref: '#/components/schemas/DomainCheckResult'
/services/{id}/domains/{domain_id}:
delete:
tags:
- Services
summary: Detach a domain
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: domain_id
in: path
required: true
schema:
type: string
responses:
'200':
description: Domain removed
/services/{id}/domains/{domain_id}/default:
post:
tags:
- Services
summary: Set the default domain
description: Marks the domain default and mirrors it to services.domain
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: domain_id
in: path
required: true
schema:
type: string
responses:
'200':
description: Updated domain list
content:
application/json:
schema:
type: object
properties:
domains:
type: array
items:
$ref: '#/components/schemas/ServiceDomain'
/maintenance:
get:
tags:
- Services
summary: Maintenance page
description: Public HTML page Traefik redirects to while a service is in maintenance mode
/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
- name: limit
in: query
schema:
type: integer
default: 50
maximum: 100
- name: cursor
in: query
description: Opaque cursor from a previous response's pagination.next_cursor
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:
get:
tags:
- Deployments
summary: List recent deployments
description: Latest deployments across all services owned by the caller — feeds the dashboard deploy feed
security:
- bearerAuth: []
parameters:
- name: limit
in: query
required: false
schema:
type: integer
default: 10
maximum: 50
- name: cursor
in: query
required: false
description: Opaque cursor from a previous response's pagination.next_cursor
schema:
type: string
responses:
'200':
description: Recent deployments
content:
application/json:
schema:
type: object
properties:
deployments:
type: array
items:
type: object
properties:
id:
type: string
service_id:
type: string
service_name:
type: string
project_name:
type: string
status:
type: string
image_name:
type: string
started_at:
type: string
nullable: true
completed_at:
type: string
nullable: true
created_at:
type: string
/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}/cancel:
post:
tags:
- Deployments
summary: Cancel a deployment
description: Cancel a queued or in-flight deployment. Queued deployments are marked cancelled immediately; running ones get their build/reconcile aborted and settle as 'cancelled' shortly after.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
description: Deployment ID
schema:
type: string
responses:
'200':
description: Queued deployment cancelled
content:
application/json:
schema:
type: object
properties:
status: { type: string, example: cancelled }
'202':
description: Running deployment is cancelling
content:
application/json:
schema:
type: object
properties:
status: { type: string, example: cancelling }
'409':
description: Deployment already finished
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/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'
post:
tags:
- Templates
summary: Create a user template
description: Create a user-owned template (JSON definition). Requires authentication; the caller becomes the template owner.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/TemplateWriteRequest'
responses:
'201':
description: Template created
content:
application/json:
schema:
type: object
properties:
template:
$ref: '#/components/schemas/ServiceTemplate'
/admin/overview:
get:
tags:
- Admin
summary: Platform overview
description: Admin-only aggregate statistics plus the pending project approval queue.
security:
- bearerAuth: []
responses:
'200':
description: Platform overview
content:
application/json:
schema:
type: object
properties:
stats:
type: object
additionalProperties:
type: integer
pending_projects:
type: array
items:
$ref: '#/components/schemas/Project'
/admin/users:
get:
tags:
- Admin
summary: List users
description: Admin-only listing of all platform users.
security:
- bearerAuth: []
responses:
'200':
description: Users retrieved
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/AdminUser'
/admin/users/{id}:
patch:
tags:
- Admin
summary: Set user admin flag
description: Grant or revoke platform admin. Admins cannot revoke their own flag.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- is_admin
properties:
is_admin:
type: boolean
responses:
'200':
description: User updated
content:
application/json:
schema:
type: object
properties:
message:
type: string
/admin/projects/{id}:
patch:
tags:
- Admin
summary: Set project approval
description: Approve or unapprove a project for public listing.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- is_approved
properties:
is_approved:
type: boolean
responses:
'200':
description: Project updated
content:
application/json:
schema:
type: object
properties:
project:
$ref: '#/components/schemas/Project'
message:
type: string
/admin/volumes:
get:
tags:
- Admin
summary: List docker volumes
description: Returns the node's docker volume inventory with in-use flags. Admin only.
security:
- bearerAuth: []
responses:
'200':
description: Volume list
content:
application/json:
schema:
type: object
properties:
volumes:
type: array
items:
$ref: '#/components/schemas/VolumeInfo'
/admin/volumes/{name}:
delete:
tags:
- Admin
summary: Delete a docker volume
description: Removes an unused docker volume. Docker refuses in-use volumes — returned as 409.
security:
- bearerAuth: []
parameters:
- name: name
in: path
required: true
schema:
type: string
responses:
'200':
description: Volume deleted
'409':
description: Volume in use or removal failed
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/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'
put:
tags:
- Templates
summary: Update a user template
description: Update a user-created template. Official templates cannot be modified; only the owner or an admin may update.
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/TemplateWriteRequest'
responses:
'200':
description: Template updated
content:
application/json:
schema:
type: object
properties:
template:
$ref: '#/components/schemas/ServiceTemplate'
delete:
tags:
- Templates
summary: Delete a user template
description: Delete a user-created template. Official templates cannot be deleted; only the owner or an admin may delete.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
description: Template ID
schema:
type: string
responses:
'200':
description: Template deleted
content:
application/json:
schema:
type: object
properties:
message:
type: string
/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.
For v2 graph templates (config.services non-empty), this deploys
the entire service graph — databases first, then services in
dependency order — and returns `resource: stack` with a `created`
list. Deployments are enqueued for each service member.
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'
/templates/{id}/plan:
post:
tags:
- Templates
summary: Dry-resolve a template
description: |
Resolves a template without creating resources: variable merging,
`{{secret}}`/`{{random:N}}`/`{{VAR}}`/`{{VAR:-default}}` expression
expansion and `{{service.<key>.<prop>}}` references. Generated
secrets are returned masked — a real deploy regenerates them.
Returns `members` (with resolved environment), `missing_variables`
and `unresolved` reference names.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
description: Template ID
schema:
type: string
requestBody:
required: false
content:
application/json:
schema:
type: object
properties:
project_id:
type: string
variables:
type: object
additionalProperties:
type: string
responses:
'200':
description: Resolved plan
content:
application/json:
schema:
type: object
properties:
members:
type: array
items:
$ref: '#/components/schemas/TemplatePlanMember'
missing_variables:
type: array
items:
type: string
unresolved:
type: array
items:
type: string
/templates/import/compose:
post:
tags:
- Templates
summary: Convert docker-compose YAML to a template graph
description: |
Parses a docker-compose YAML document and returns a v2 template
config (`version: 2`, `services[]`). Well-known database images
(postgres, redis, mongo, mysql, mariadb, clickhouse, dragonfly)
become managed-database members; other images become web services.
`build:` contexts are flagged in `warnings` — Containr deploys
images or git repos, not local build contexts. The returned config
can be saved via POST /templates or deployed directly via
POST /templates/deploy.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- compose_yaml
properties:
compose_yaml:
type: string
description: Raw docker-compose YAML (max 512 KiB)
responses:
'200':
description: Converted config
content:
application/json:
schema:
type: object
properties:
config:
$ref: '#/components/schemas/TemplateConfig'
variables:
type: array
items:
type: object
warnings:
type: array
items:
type: string
/templates/deploy:
post:
tags:
- Templates
summary: Deploy an ad-hoc service graph
description: |
Deploys a v2 graph config (config.services[]) without a stored
template — the companion to POST /templates/import/compose.
Members are created in dependency order; `database` members become
managed databases attached to the project network under their key
as DNS alias, and deployments are enqueued for service members.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- project_id
- config
properties:
project_id:
type: string
config:
$ref: '#/components/schemas/TemplateConfig'
variables:
type: object
additionalProperties:
type: string
plan:
type: string
region:
type: string
responses:
'201':
description: Graph deployed
content:
application/json:
schema:
type: object
properties:
resource:
type: string
created:
type: array
items:
type: object
properties:
key:
type: string
kind:
type: string
id:
type: string
name:
type: string
deployment_id:
type: string
# 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/register-external:
post:
tags:
- Databases
summary: Register external database
description: Record a database hosted elsewhere — connection is probed first (postgres/redis get protocol-level checks, others TCP). Password stored encrypted, never returned.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/ExternalDatabaseRequest'
- type: object
required: [name]
responses:
'201':
description: External database registered
'400':
description: Validation failed or connection probe failed
'409':
description: Name already in use
/databases/test-connection:
post:
tags:
- Databases
summary: Probe a database connection
description: Ad-hoc connectivity check — postgres via libpq ping, redis/dragonfly via PING, other engines via TCP dial. Always 200; `ok` carries the result.
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ExternalDatabaseRequest'
responses:
'200':
description: Probe result
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
latency_ms:
type: integer
error:
type: string
/databases/{id}/test-connection:
post:
tags:
- Databases
summary: Re-probe a registered external database
description: Uses the stored credentials. External databases only.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Probe result (`ok` carries the outcome)
'404':
description: Database not found
/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/import:
post:
tags:
- Databases
summary: Import a backup archive
description: >-
Upload a `.tar.gz` archive (multipart field `file` or a raw
application/gzip body) to create a new restore point. The archive
lands in the backup volume and, when a backup target is assigned,
is also shipped offsite. Managed databases only; 2 GiB ceiling.
security:
- bearerAuth: []
parameters:
- name: id
in: path
required: true
description: Database ID
schema:
type: string
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
application/gzip:
schema:
type: string
format: binary
responses:
'201':
description: Backup imported
content:
application/json:
schema:
type: object
properties:
backup_id:
type: string
size:
type: string
status:
type: string
'400':
description: Invalid archive
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'413':
description: Archive too large
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/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'
/projects/{id}/variables:
get:
tags:
- Projects
summary: List shared project variables
description: Project-level variables shared across services. Services reference them as `${{shared.KEY}}` in environment values — resolved at deploy/reconcile, not live-updated. 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: Project not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
put:
tags:
- Projects
summary: Replace shared project variables
description: Replace the full shared-variable set for a project. Fetch the current list first and merge — the server replaces wholesale. Masked secret placeholders (`********`) keep the stored value.
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
AdminUser:
type: object
properties:
id:
type: string
email:
type: string
format: email
name:
type: string
avatar_url:
type: string
is_admin:
type: boolean
created_at:
type: string
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
is_approved:
type: boolean
description: Whether the project is approved for public listing. New projects default to false and appear publicly only after admin approval.
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)
volumes:
type: array
items:
$ref: '#/components/schemas/ServiceVolume'
description: Volume/bind mounts applied to every replica
domains:
type: array
items:
$ref: '#/components/schemas/ServiceDomain'
description: All attached hostnames; `domain` is the derived default
maintenance_mode:
type: boolean
description: Redirect all traffic to the platform maintenance page
basic_auth:
type: array
items:
type: string
description: Basic-auth usernames gating the route (hashes never returned)
builder:
type: string
enum: [auto, railpack, nixpacks, dockerfile, static]
description: Build strategy; auto detects from repo contents
cpu_reserve:
type: string
description: Soft CPU reservation (fraction, e.g. 0.25 → ~256 CPU shares)
memory_reserve:
type: string
description: Soft memory reservation (e.g. 128Mi)
static_build_cmd:
type: string
description: Build command for the static builder (default "npm ci && npm run build")
static_dir:
type: string
description: Output directory for the static builder (default dist)
sleep_enabled:
type: boolean
description: Scale to zero after sleep_idle_minutes without inbound traffic; a wake placeholder answers requests while the service resumes
sleep_idle_minutes:
type: integer
description: Idle timeout in minutes before sleeping (1-1440, default 15)
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
volumes:
type: array
items:
$ref: '#/components/schemas/ServiceVolume'
description: Volume/bind mounts applied to every replica
builder:
type: string
enum: [auto, railpack, nixpacks, dockerfile, static]
description: Build strategy (default auto)
cpu_reserve:
type: string
description: Soft CPU reservation (fraction, e.g. 0.25)
memory_reserve:
type: string
description: Soft memory reservation (e.g. 128Mi)
static_build_cmd:
type: string
description: Build command for the static builder
static_dir:
type: string
description: Output directory for the static builder (default dist)
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
volumes:
type: array
items:
$ref: '#/components/schemas/ServiceVolume'
description: Replaces the entire mount list when present; [] clears all mounts. Takes effect on next deploy/reconcile.
maintenance_mode:
type: boolean
description: Redirect all traffic to the platform maintenance page
basic_auth:
type: array
items:
$ref: '#/components/schemas/BasicAuthCred'
description: Replaces all basic-auth credentials; [] clears the gate
builder:
type: string
enum: [auto, railpack, nixpacks, dockerfile, static]
description: Build strategy
cpu_reserve:
type: string
description: Soft CPU reservation (empty string clears)
memory_reserve:
type: string
description: Soft memory reservation (empty string clears)
static_build_cmd:
type: string
description: Build command for the static builder (empty string clears)
static_dir:
type: string
description: Output directory for the static builder (empty string clears)
sleep_enabled:
type: boolean
description: Scale to zero after sleep_idle_minutes without inbound traffic; a wake placeholder answers requests while resuming
sleep_idle_minutes:
type: integer
description: Idle timeout in minutes before sleeping (1-1440)
ServiceDomain:
type: object
properties:
id:
type: string
format: uuid
service_id:
type: string
format: uuid
domain:
type: string
is_default:
type: boolean
cert_type:
type: string
cert_status:
type: string
enum: [pending, issued, failed]
last_checked_at:
type: string
format: date-time
created_at:
type: string
format: date-time
DomainCheckResult:
type: object
properties:
domain:
type: string
status:
type: string
enum: [ok, wrong-target, pending]
description: ok = resolves to expected target (or no expectation configured), wrong-target = resolves elsewhere, pending = no DNS records
resolved:
type: array
items:
type: string
description: A/AAAA records resolved
BasicAuthCred:
type: object
required:
- username
- password
properties:
username:
type: string
password:
type: string
description: Plaintext on write — stored as bcrypt htpasswd; never returned
Registry:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
host:
type: string
description: Registry host matched against the image reference — ghcr.io, registry.example.com, docker.io for Docker Hub
username:
type: string
has_password:
type: boolean
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
RegistryRequest:
type: object
required:
- name
- host
properties:
name:
type: string
host:
type: string
username:
type: string
password:
type: string
description: Plaintext on write — stored encrypted; never returned. Empty on update keeps the stored credential.
ServiceVolume:
type: object
required:
- source
- target
properties:
type:
type: string
enum: [volume, bind]
default: volume
description: volume = docker named volume, bind = host path
source:
type: string
description: Volume name or host path
target:
type: string
description: Absolute container path
read_only:
type: boolean
default: false
VolumeInfo:
type: object
properties:
name:
type: string
driver:
type: string
mountpoint:
type: string
scope:
type: string
in_use:
type: boolean
used_by:
type: array
items:
type: string
description: Container names mounting this volume
created_at:
type: string
format: date-time
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
no_cache:
type: boolean
description: Build without Docker layer cache
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
owner_id:
type: string
nullable: true
description: Owning user ID for user-created templates; null for official presets
is_public:
type: boolean
description: Whether a user-created template is published to the public catalog
created_at:
type: string
format: date-time
description: Creation timestamp
updated_at:
type: string
format: date-time
description: Last update timestamp
TemplateWriteRequest:
type: object
required:
- name
- config
properties:
name:
type: string
description: Template display name
description:
type: string
description: Template description
category:
type: string
description: Template category (web, database, cache, queue, monitoring, storage, app, other)
logo:
type: string
description: Template logo URL
config:
type: object
description: Template config object (type, runtime, commands, port, environment)
variables:
type: array
items:
$ref: '#/components/schemas/TemplateVariable'
description: Configurable variables exposed at deploy time
is_public:
type: boolean
description: Publish this template to the public catalog (visible anonymously)
TemplateConfig:
type: object
properties:
version:
type: integer
description: Config version — 2 when services[] is used
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
services:
type: array
description: |
v2 graph members. When non-empty, the flat fields above are
ignored and deploy creates the whole graph in dependency order.
items:
$ref: '#/components/schemas/TemplateServiceSpec'
TemplateServiceSpec:
type: object
required:
- key
- type
properties:
key:
type: string
description: Member key — DNS alias on the project network and the target of {{service.<key>.*}} refs
name:
type: string
description: Display/deployed name (defaults to key)
type:
type: string
enum: [web, worker, cron, database]
runtime:
type: string
description: Image reference (web/worker/cron) or managed engine (database)
repo:
type: string
description: Git repository URL — when set, the member builds from source
branch:
type: string
build_command:
type: string
start_command:
type: string
port:
type: integer
health_check:
type: string
builder:
type: string
enum: [auto, nixpacks, dockerfile, static]
environment:
type: object
additionalProperties:
type: string
description: |
Env vars. Values support {{secret}}, {{secret(N)}}, {{random:N}},
{{VAR}}, {{VAR:-default}} and {{service.<key>.<prop>}} where prop
is host, port, url, user, password or database.
volumes:
type: array
items:
$ref: '#/components/schemas/ServiceVolume'
depends_on:
type: array
items:
type: string
description: Member keys that must be created first
TemplatePlanMember:
type: object
properties:
key:
type: string
name:
type: string
type:
type: string
runtime:
type: string
port:
type: integer
depends_on:
type: array
items:
type: string
environment:
type: object
additionalProperties:
type: string
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, stack]
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)
created:
type: array
description: Created resources (set for graph templates — resource=stack)
items:
type: object
properties:
key:
type: string
kind:
type: string
enum: [service, database]
id:
type: string
name:
type: string
deployment_id:
type: string
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
provider:
type: string
enum: [managed, external]
description: managed = Containr-provisioned container; external = registered connection to a database hosted elsewhere
public_port:
type: boolean
description: managed only — bind the database port on all interfaces instead of 127.0.0.1; toggling recreates the container
backup_target_id:
type: string
description: S3-compatible backup target receiving this database's archives, empty when local-only
external:
$ref: '#/components/schemas/DatabaseExternal'
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
public_port:
type: boolean
description: Bind the database port on all interfaces (default 127.0.0.1)
DatabaseExternal:
type: object
properties:
host:
type: string
port:
type: integer
database:
type: string
username:
type: string
has_password:
type: boolean
ssl:
type: boolean
ExternalDatabaseRequest:
type: object
required:
- type
- host
properties:
name:
type: string
description: Display name (required for register, unused for probes)
type:
type: string
enum: [postgresql, redis, mysql, mariadb, mongodb, clickhouse, dragonfly]
host:
type: string
port:
type: integer
description: Defaults to the engine's standard port
database:
type: string
username:
type: string
password:
type: string
description: Stored encrypted; never returned
ssl:
type: boolean
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
public_port:
type: boolean
description: Toggle the published port between 127.0.0.1 and all interfaces; recreates the managed container
backup_target_id:
type: string
nullable: true
description: Assign a backup target for offsite archives; empty string clears
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]
remote:
type: boolean
description: Archive also shipped to the database's configured backup target
BackupTarget:
type: object
properties:
id:
type: string
name:
type: string
endpoint:
type: string
description: Bare host[:port] — scheme comes from use_tls
bucket:
type: string
region:
type: string
prefix:
type: string
has_credentials:
type: boolean
use_tls:
type: boolean
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
BackupTargetRequest:
type: object
required:
- endpoint
- bucket
properties:
name:
type: string
endpoint:
type: string
bucket:
type: string
region:
type: string
prefix:
type: string
access_key:
type: string
description: Stored encrypted; never returned. Empty on update keeps stored credentials.
secret_key:
type: string
description: Stored encrypted; never returned. Empty on update keeps stored credentials.
use_tls:
type: boolean
default: true
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'
redeploy:
type: boolean
description: Queue a service redeploy after saving so running containers pick up the new variables
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
os:
type: string
scope:
type: string
description: What the telemetry measures — `host` for a native daemon, `docker-desktop-vm` when Docker runs inside a Desktop VM.
enum: [host, docker-desktop-vm]
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)
UserToken:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
key_prefix:
type: string
description: First 12 chars of the token, for identification in lists
scope:
type: string
enum: [read, write, admin]
expires_at:
type: string
format: date-time
last_used_at:
type: string
format: date-time
created_at:
type: string
format: date-time
required:
- id
- name
- key_prefix
- scope
- created_at
UserTokenCreated:
allOf:
- $ref: '#/components/schemas/UserToken'
- type: object
properties:
token:
type: string
description: Raw cnp_ token value, returned exactly once at creation
required:
- token
CreateUserTokenRequest:
type: object
properties:
name:
type: string
description: Human-readable label (e.g. "laptop cli", "ci deploy")
scope:
type: string
enum: [read, write, admin]
default: write
description: read = GET/HEAD only; write = all non-admin routes; admin = everything (requires admin account)
expires_in_days:
type: integer
minimum: 0
maximum: 3650
description: 0 or omitted = never expires
required:
- 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: Registries
description: Private-image pull credentials
- name: BackupTargets
description: S3-compatible backup destinations for managed databases
- name: Gateway
description: API gateway — upstream services, keys, analytics