API Reference

Endpoints Reference

Complete reference for all FlatRun API endpoints.

This page provides worked examples for common endpoints. The complete reference comes from the running agent at /api/openapi.json, so it always matches the installed version.

flatrun deployments create --help
flatrun deployments create --generate-cli-skeleton
Preview changes first. Operations marked as plan capable accept --plan in the CLI or ?plan=true over HTTP. Read the returned changes, then apply the plan with POST /api/plans/:id/apply.

Deployments

GET /api/deployments

List all deployments.

Response

[
  {
    "name": "my-wordpress",
    "path": "/var/flatrun/deployments/my-wordpress",
    "status": "running",
    "created_at": "2024-01-01T00:00:00Z",
    "services": [
      {"name": "wordpress", "status": "running", "health": "healthy"}
    ]
  }
]
GET /api/deployments/:name

Get detailed information about a specific deployment.

Parameters

  • name: Deployment name
POST /api/deployments

Create a new deployment.

Request Body

{
  "name": "my-app",
  "compose_content": "services:\n  app:\n    image: nginx:alpine\n",
  "env_vars": [{"key": "APP_ENV", "value": "staging"}],
  "auto_start": true
}
POST /api/deployments/:name/start

Start a stopped deployment.

POST /api/deployments/:name/stop

Stop a running deployment.

POST /api/deployments/:name/restart

Restart a deployment.

DELETE /api/deployments/:name

Delete a deployment.

Query Parameters

  • remove_files: Also delete deployment directory (default: false)
GET /api/deployments/:name/logs

Get deployment logs.

Query Parameters

  • tail: Number of lines (default: 100, 0 for all)
  • service: One compose service, or omit for every service
  • source: stdout for container output, or the id of a file source
  • filter: Keep only lines containing this text
GET /api/deployments/:name/logs/stream

Follow deployment logs over a websocket, taking the same query parameters. The auth token is sent as the first message.

GET /api/deployments/:name/log-sources

List the log sources offered for a deployment: container output, the built-in file sources for its kind, and any custom ones.

PUT /api/deployments/:name/log-sources

Add or replace custom file sources. Paths are relative to the deployment directory.

GET /api/deployments/:name/stats

Get resource usage statistics for all containers in deployment.

Domains (Multi-Domain)

GET /api/deployments/:name/domains

List all domains configured for a deployment.

POST /api/deployments/:name/domains

Add a new domain to a deployment.

Request Body

{
  "service": "web",
  "domain": "blog.example.com",
  "container_port": 80,
  "path_prefix": "/",
  "strip_prefix": false,
  "ssl": {
    "enabled": true
  },
  "aliases": ["www.blog.example.com"]
}
PUT /api/deployments/:name/domains/:domainId

Update an existing domain configuration.

DELETE /api/deployments/:name/domains/:domainId

Remove a domain from a deployment.

Containers

GET /api/containers

List all Docker containers.

Query Parameters

  • all: Include stopped containers (default: true)
POST /api/containers/:id/start

Start a container.

POST /api/containers/:id/stop

Stop a container.

POST /api/containers/:id/restart

Restart a container.

DELETE /api/containers/:id

Remove a container (must be stopped).

GET /api/containers/:id/logs

Get container logs.

Templates

GET /api/templates

List all available templates.

GET /api/templates/categories

Get template categories with counts.

POST /api/templates/refresh

Reload templates from disk.

GET /api/templates/:id/compose

Get template's docker-compose.yml content.

Certificates

GET /api/certificates

List all SSL certificates.

POST /api/certificates

Request a new SSL certificate.

Request Body

{
  "domain": "example.com"
}
POST /api/certificates/renew

Renew all expiring certificates.

DELETE /api/certificates/:domain

Delete a certificate.

Proxy

GET /api/proxy/status/:name

Get proxy configuration status for a deployment.

POST /api/proxy/setup/:name

Configure reverse proxy for a deployment.

Request Body

{
  "domain": "app.example.com",
  "port": 80,
  "ssl": true
}
DELETE /api/proxy/:name

Remove proxy configuration.

Databases

POST /api/databases/test

Test database connection.

POST /api/databases/list

List all databases on the server.

POST /api/databases/tables

List tables in a database.

Request Body

{
  "database": "myapp"
}
POST /api/databases/query

Execute a SQL query.

Request Body

{
  "database": "myapp",
  "query": "SELECT * FROM users LIMIT 10"
}
POST /api/databases/create

Create a new database.

POST /api/databases/users/create

Create a database user.

POST /api/databases/privileges/grant

Grant privileges to a user.

Infrastructure

GET /api/infrastructure

List infrastructure services.

POST /api/infrastructure/:name/start

Start an infrastructure service.

POST /api/infrastructure/:name/stop

Stop an infrastructure service.

Security

GET /api/security/stats

Get security statistics overview.

GET /api/security/events

List security events with pagination and filtering.

Query Parameters

  • type: Filter by event type
  • source_ip: Filter by source IP
  • deployment: Filter by deployment
  • start_time: Start of time range (RFC3339)
  • end_time: End of time range (RFC3339)
  • limit: Number of results (default: 50)
  • offset: Pagination offset
GET /api/security/events/:id

Get a single security event by ID.

POST /api/security/cleanup

Remove old security events.

Request Body

{
  "older_than": 604800  // Seconds
}
GET /api/security/blocked-ips

List all blocked IP addresses.

POST /api/security/blocked-ips

Block an IP address.

Request Body

{
  "ip": "192.168.1.100",
  "reason": "Suspicious activity",
  "duration": 86400  // Seconds (optional)
}
DELETE /api/security/blocked-ips/:ip

Unblock an IP address.

GET /api/security/ips/:ip/events

Get all security events for a specific IP.

GET /api/security/protected-routes

List all protected routes.

POST /api/security/protected-routes

Add a protected route.

Request Body

{
  "path": "/admin",
  "method": "ALL",
  "auth_type": "basic",
  "credentials": "admin:secret",
  "deployment": "my-app"
}
PUT /api/security/protected-routes/:id

Update a protected route.

DELETE /api/security/protected-routes/:id

Delete a protected route.

GET /api/security/whitelist

List whitelist entries.

POST /api/security/whitelist

Add a whitelist entry.

Request Body

{
  "type": "ip",  // ip, cidr, or path
  "value": "10.0.0.0/8",
  "description": "Internal network"
}
DELETE /api/security/whitelist/:id

Remove a whitelist entry.

GET /api/security/realtime-capture

Get real-time capture status.

PUT /api/security/realtime-capture

Enable or disable real-time capture.

Request Body

{
  "enabled": true
}
POST /api/security/refresh

Regenerate Lua scripts and reload nginx.

GET /api/deployments/:name/security

Get security settings for a deployment.

PUT /api/deployments/:name/security

Update deployment security settings.

Backups

GET /api/backups

List all backups.

Query Parameters

  • deployment: Filter by deployment name
GET /api/backups/:id

Get backup details.

POST /api/backups

Create a backup.

Request Body

{
  "deployment_name": "my-wordpress",
  "include_files": true,
  "include_database": true,
  "exclude_patterns": ["*.log", "cache/*"],
  "description": "Pre-upgrade backup"
}

Response

{
  "job_id": "backup-123456",
  "message": "Backup job started"
}
DELETE /api/backups/:id

Delete a backup.

GET /api/backups/:id/download

Download backup archive.

POST /api/backups/:id/restore

Restore from a backup.

Request Body

{
  "target_name": "my-wordpress",
  "restore_database": true,
  "restore_files": true,
  "auto_start": true
}
GET /api/backups/jobs

List backup/restore jobs.

GET /api/backups/jobs/:id

Get job status.

GET /api/deployments/:name/backups

List backups for a deployment.

GET /api/deployments/:name/backup-config

Get backup configuration for a deployment.

PUT /api/deployments/:name/backup-config

Update backup configuration for a deployment.

Request Body

{
  "enabled": true,
  "schedule": "0 2 * * *",
  "retention": 7,
  "include_database": true,
  "exclude_patterns": ["*.log"]
}

Object Stores

GET /api/backup-destinations

List the object stores this agent knows about, external and FlatRun-managed.

POST /api/object-stores/provision-managed

Deploy an object store on this host from a template and register it, credentials included.

GET /api/object-stores/:name/buckets

List a store's buckets. POST the same path to create one, DELETE /api/object-stores/:name/buckets/:bucket to remove one.

GET /api/object-stores/:name/objects

List objects. POST uploads, GET /objects/download downloads, DELETE /objects removes.

POST /api/object-stores/:name/attach

Give a deployment this store's endpoint and credentials so the application can use it.

POST /api/object-stores/:name/replicate

Sync this store to another one, for an offsite copy or a local cache.

Plans

Add ?plan=true to a mutating request and it returns a preview instead of executing. See Plan & Apply.

GET /api/plans

List plans and their status.

GET /api/plans/:id

Get one plan, with sensitive values redacted.

POST /api/plans/:id/apply

Run the reviewed change. Refused with 409 if a file it depends on changed since the plan was created, and with 410 once the plan has expired.

DELETE /api/plans/:id

Discard a plan.

Metrics & Alerts

Served by the observability app through the agent's plugin proxy.

GET /api/plugin/observability/metrics/latest

The most recent reading for every container, grouped by deployment.

GET /api/plugin/observability/metrics/timeseries

History for one deployment. /metrics/host does the same for the host, /metrics/series for a single container and metric.

GET /api/plugin/observability/metrics/prometheus

The same readings in the Prometheus text exposition format, for scraping.

GET /api/plugin/observability/alerts/rules

Alert rules. PUT the same path to replace them. /alerts/firing is what is breached now, /alerts/events the history.

GET /api/plugin/observability/health

Each container's health. /health/events lists the recoveries the watcher performed.

GET /api/dashboards

Saved dashboards. POST to create, GET /api/dashboards/:id to read one, DELETE to remove.

Notifications

GET /api/notifications/targets

Delivery targets as shoutrrr URLs, covering webhooks, chat services, and email. PUT to replace them.

POST /api/notifications/test

Send a test message, so a target is known to work before an incident depends on it.

Scheduler

GET /api/scheduler/tasks

List scheduled tasks.

Query Parameters

  • deployment: Filter by deployment name
GET /api/scheduler/tasks/:id

Get scheduled task details.

POST /api/scheduler/tasks

Create a scheduled task.

Request Body

{
  "deployment_name": "my-wordpress",
  "task_type": "backup",
  "cron_expr": "0 2 * * *",
  "action": "",
  "description": "Daily backup at 2 AM"
}
PUT /api/scheduler/tasks/:id

Update a scheduled task.

DELETE /api/scheduler/tasks/:id

Delete a scheduled task.

POST /api/scheduler/tasks/:id/run

Execute a task immediately.

GET /api/scheduler/tasks/:id/executions

Get execution history for a task.

GET /api/scheduler/executions

Get recent executions across all tasks.

Users

GET /api/users/me

Get current authenticated user.

PUT /api/users/me

Update current user profile.

PUT /api/users/me/password

Change current user password.

Request Body

{
  "current_password": "old-password",
  "new_password": "new-password"
}
GET /api/users

List all users (admin only).

GET /api/users/:id

Get user details.

POST /api/users

Create a new user.

Request Body

{
  "username": "john",
  "email": "[email protected]",
  "password": "secure-password",
  "role": "operator",
  "permissions": ["deployments:read", "deployments:write"]
}
PUT /api/users/:id

Update a user.

DELETE /api/users/:id

Delete a user.

GET /api/users/:id/deployments

Get deployments assigned to a user.

POST /api/users/:id/deployments

Assign a deployment to a user.

Request Body

{
  "deployment_name": "my-app",
  "access_level": "write"  // read, write, or admin
}
PUT /api/users/:id/deployments/:name

Update deployment access level for a user.

DELETE /api/users/:id/deployments/:name

Remove deployment access from a user.

GET /api/deployments/:name/users

Get users with access to a deployment.

API Keys

GET /api/apikeys

List API keys (user's own keys or all if admin).

GET /api/apikeys/:id

Get API key details.

POST /api/apikeys

Create a new API key.

Request Body

{
  "name": "CI/CD Key",
  "description": "For GitHub Actions",
  "role": "operator",
  "permissions": ["deployments:read", "deployments:write"],
  "deployments": ["my-app", "my-api"],
  "expires_in": 2592000  // Seconds (optional)
}

Response

{
  "id": 1,
  "key": "flatrun_xxxxxxxxxxxx",  // Only shown once
  "name": "CI/CD Key",
  "created_at": "2024-01-01T00:00:00Z"
}
DELETE /api/apikeys/:id

Delete an API key.

POST /api/apikeys/:id/revoke

Revoke an API key (deactivate without deleting).

Traffic

GET /api/traffic/logs

Get traffic logs with filtering.

Query Parameters

  • deployment: Filter by deployment
  • method: HTTP method (GET, POST, etc.)
  • status_group: Status group (2xx, 4xx, 5xx)
  • status_code: Specific status code
  • source_ip: Source IP address
  • path: URL path pattern
  • start_time: Start of time range (RFC3339)
  • end_time: End of time range (RFC3339)
  • limit: Number of results (default: 100)
  • offset: Pagination offset
GET /api/traffic/stats

Get aggregated traffic statistics.

GET /api/traffic/unknown-domains

Get traffic stats for unknown domains.

POST /api/traffic/cleanup

Remove old traffic logs.

GET /api/deployments/:name/traffic

Get traffic stats for a specific deployment.

Audit

GET /api/audit/events

List audit events with filtering.

Query Parameters

  • actor_id: Filter by actor ID
  • actor_type: Filter by actor type (user, api_key, system)
  • action: Filter by action
  • resource_type: Filter by resource type
  • resource_id: Filter by resource ID
  • success: Filter by success status
  • client_ip: Filter by client IP
  • start_time: Start of time range (RFC3339)
  • end_time: End of time range (RFC3339)
  • limit: Number of results (default: 50, max: 1000)
  • offset: Pagination offset
GET /api/audit/events/:id

Get a single audit event.

GET /api/audit/stats

Get audit statistics.

POST /api/audit/export

Export audit events.

Request Body

{
  "format": "json",  // or "csv"
  "actor_type": "user",
  "start_time": "2024-01-01T00:00:00Z",
  "end_time": "2024-01-31T23:59:59Z",
  "limit": 1000
}
DELETE /api/audit/cleanup

Remove old audit events.

DNS

GET /api/dns/providers

List available DNS providers.

GET /api/dns/powerdns/status

Get PowerDNS service status.

POST /api/dns/powerdns/enable

Enable PowerDNS service.

POST /api/dns/powerdns/disable

Disable PowerDNS service.

POST /api/dns/powerdns/restart

Restart PowerDNS service.

GET /api/dns/powerdns/zones

List DNS zones.

POST /api/dns/powerdns/zones

Create a DNS zone.

Request Body

{
  "name": "example.com.",
  "kind": "Master",
  "nameservers": [
    "ns1.example.com.",
    "ns2.example.com."
  ]
}
GET /api/dns/powerdns/zones/:zoneId

Get zone details with records.

DELETE /api/dns/powerdns/zones/:zoneId

Delete a DNS zone.

PATCH /api/dns/powerdns/zones/:zoneId

Update zone records (RRSets).

Request Body

{
  "rrsets": [
    {
      "name": "www.example.com.",
      "type": "A",
      "ttl": 3600,
      "changetype": "REPLACE",
      "records": [
        {"content": "192.168.1.100", "disabled": false}
      ]
    }
  ]
}

Plugins & Registries

GET /api/plugins

List available plugins.

GET /api/plugins/:name

Get plugin details.

POST /api/plugins/:name/deployments

Create a deployment from a plugin.

GET /api/registries

List registry configurations.

GET /api/registries/:slug

Get registry details.

POST /api/registries

Create a registry configuration.

PUT /api/registries/:slug

Update a registry configuration.

DELETE /api/registries/:slug

Delete a registry configuration.

Credentials

GET /api/credentials

List credentials.

GET /api/credentials/:id

Get credential details.

POST /api/credentials

Create a credential.

Request Body

{
  "name": "docker-hub",
  "type": "docker-registry",
  "credentials": {
    "username": "myuser",
    "password": "mytoken"
  }
}
PUT /api/credentials/:id

Update a credential.

DELETE /api/credentials/:id

Delete a credential.

POST /api/credentials/:id/test

Test credential validity.

System

GET /api/health

Health check endpoint (no auth required).

Response

{
  "status": "ok",
  "version": "0.1.4",
  "uptime": "24h30m"
}
GET /api/system/logs/sources

List the host's own log sources: the proxy's access and error logs, and shared infrastructure containers.

GET /api/system/logs

Read a system log source.

Query Parameters

  • source: Source id, for example nginx-access
  • tail: Number of lines (default: 100, 0 for all)
  • filter: Keep only lines containing this text
  • deployment: Keep only the access lines for one deployment's domains
GET /api/system/logs/stream

Follow a system log source over a websocket, taking the same query parameters.

GET /api/settings

Get current agent settings.

PUT /api/settings

Update agent settings.

PUT /api/settings/security

Update security settings.

GET /api/auth/status

Get current authentication status.

POST /api/auth/login

Authenticate and get a token.

Request Body

{
  "username": "admin",
  "password": "password"
}
GET /api/auth/validate

Validate current token.

Star us on GitHub