Files
CLICD/docs/en/features/api.md
T
MengMengCode a45e063fc2 Add comprehensive documentation for CLICD features and operations
- Introduced Container Management documentation covering lifecycle operations, resource management, and console access.
- Added Dashboard documentation detailing metrics and related APIs.
- Created Host Report documentation summarizing host environment and resource status.
- Included Image Management documentation for template handling and management actions.
- Documented Networking and Routing features including NAT4 and IPv6 management.
- Added Security Alerts documentation outlining alert scenarios and API usage.
- Created Snapshot Management documentation for snapshot operations and scheduling.
- Documented Sub-user management for granting access to specific containers.
- Added Configuration guide detailing runtime settings and security recommendations.
- Created Installation guide for setting up CLICD with requirements and steps.
- Added Introduction and Quick Start guides for new users.
- Documented Upgrade process with version checking and pre-upgrade checklist.
- Created Deployment guide for service exposure and firewall recommendations.
- Added FAQ section addressing common questions and concerns.
- Documented Troubleshooting steps for common issues encountered.
2026-06-10 00:42:06 +08:00

21 KiB

API Integration

CLICD remains compatible with legacy /api endpoints, so existing integrations do not need to change. New integrations should use /api/v1; the list below is all v1, and the recommended container list endpoint is GET /api/v1/containers.

Authentication

API keys can be created and managed from the API Integration page. Requests support either of these headers:

curl -H "X-API-Key: YOUR_API_KEY" https://panel.example.com/api/v1/containers
curl -H "Authorization: Bearer YOUR_API_KEY" https://panel.example.com/api/v1/dashboard

Response Shape

All APIs use the same response envelope:

{
  "success": true,
  "message": "OK",
  "data": {}
}

Integrations should read only the business fields they need. New capabilities are added as optional fields where possible, without requiring existing plugins to rename current fields.

Creation and Reinstall

Container creation, batch creation, reinstall, and batch reinstall support mixed NAT, public IPv4, IPv6 networking, plus Linux SSH login configuration. Public IPv4/IPv6 pools can be viewed with GET /api/v1/routing and updated with PUT /api/v1/routing.

Create container example:

{
  "name": "demo-lxc-01",
  "virtualization": "lxc",
  "template_id": "debian-bookworm",
  "vcpu": 1,
  "ram_mb": 512,
  "disk_gb": 10,
  "assign_nat": true,
  "port_mapping_count": 2,
  "assign_ipv4": false,
  "ipv4_count": 1,
  "public_ipv4s": [],
  "assign_ipv6": true,
  "ipv6_count": 1,
  "ipv6_addresses": [],
  "ssh_auth_mode": "auto_password",
  "ssh_password": "",
  "ssh_public_key": "",
  "expires_at": ""
}

Field notes:

Field Description
assign_nat Whether to allocate NAT port mappings. If omitted, default NAT behavior is preserved.
assign_ipv4 Whether to allocate public IPv4.
ipv4_count Number of public IPv4 addresses to allocate automatically.
public_ipv4s Explicit public IPv4 address list.
assign_ipv6 Whether to allocate IPv6.
ipv6_count Number of IPv6 addresses to allocate automatically.
ipv6_addresses Explicit IPv6 address list.
ssh_auth_mode Linux creation supports auto_password, password, and key; reinstall also supports keep.
ssh_password Custom password for password mode. It must be 8-64 characters, include letters and digits, and contain no whitespace.
ssh_public_key One-line SSH public key for key mode.

Reinstall example:

{
  "template_id": "debian-bookworm",
  "ssh_auth_mode": "keep",
  "ssh_password": "",
  "ssh_public_key": ""
}

keep is only for reinstall and keeps the current SSH password. Windows KVM images ignore Linux SSH public key fields.

Python Example

Fetch containers:

import requests

BASE_URL = "https://panel.example.com"
API_KEY = "YOUR_API_KEY"

session = requests.Session()
session.headers.update({
    "X-API-Key": API_KEY,
    "Content-Type": "application/json",
})

resp = session.get(f"{BASE_URL}/api/v1/containers", timeout=15)
resp.raise_for_status()
print(resp.json())

Create a port mapping:

import requests

BASE_URL = "https://panel.example.com"
API_KEY = "YOUR_API_KEY"
CONTAINER_ID = "example-vm"

payload = {
    "protocol": "tcp",
    "host_port": 18080,
    "container_port": 80,
    "description": "web",
}

resp = requests.post(
    f"{BASE_URL}/api/v1/containers/{CONTAINER_ID}/port-mappings",
    headers={"X-API-Key": API_KEY},
    json=payload,
    timeout=15,
)
resp.raise_for_status()
print(resp.json())

Endpoint List

Overview

Method Path Description
GET /api/v1/dashboard Dashboard statistics
GET /api/v1/host-info Host resources
GET /api/v1/routing NAT/IPv4/IPv6 routing
PUT /api/v1/routing Update public IPv4/IPv6 pools
POST /api/v1/routing/ipv4-scan Scan a public IPv4 segment
GET /api/v1/ipv6/status IPv6 status
GET /api/v1/tasks Task queue
DELETE /api/v1/tasks/{task_id} Delete a task

Containers

Method Path Description
GET /api/v1/containers Container list
POST /api/v1/containers/list Compatible POST form for container list
POST /api/v1/containers Create container
GET `/api/v1/containers/{id uuid
POST /api/v1/containers/{id}/start Start
POST /api/v1/containers/{id}/stop Stop
POST /api/v1/containers/{id}/restart Restart
POST /api/v1/containers/{id}/reinstall Reinstall
DELETE /api/v1/containers/{id}/delete Delete
GET /api/v1/containers/{id}/usage Resource usage
GET /api/v1/containers/{id}/traffic Traffic statistics
POST /api/v1/containers/{id}/traffic-reset Reset traffic
PUT /api/v1/containers/{id}/traffic-limit Update traffic limits
PUT /api/v1/containers/{id}/resource-limit Update resource limits
PUT /api/v1/containers/{id}/expiry Update expiration time
POST /api/v1/containers/{id}/reset-password Reset SSH password
POST /api/v1/containers/{id}/ipv6 Assign IPv6

Ports and Snapshots

Method Path Description
GET /api/v1/containers/{id}/random-port Random available port
POST /api/v1/containers/{id}/port-mappings Add port mapping
PUT /api/v1/containers/{id}/port-mappings/{index} Update port mapping
DELETE /api/v1/containers/{id}/port-mappings/{index} Delete port mapping
GET /api/v1/snapshots Snapshot overview
GET /api/v1/containers/{id}/snapshots Container snapshots
POST /api/v1/containers/{id}/snapshots Create snapshot
DELETE /api/v1/containers/{id}/snapshots/{snapshot_id} Delete snapshot
POST /api/v1/containers/{id}/snapshots/{snapshot_id}/restore Restore snapshot
POST /api/v1/containers/{id}/snapshots/schedule Schedule snapshots
PUT /api/v1/containers/{id}/snapshots/quota Snapshot quota

Platform Management

Method Path Description
GET /api/v1/templates Template list
GET /api/v1/images Image management list
POST /api/v1/images/download Download image
POST /api/v1/images/cancel Cancel image download
DELETE /api/v1/images/delete Delete image cache
PUT /api/v1/images/toggle Enable or disable image
GET /api/v1/security/alerts Security alerts
POST /api/v1/security/check Run security check
GET /api/v1/security/logs?container={name} Security connection logs
GET /api/v1/security/summary Security summary
GET /api/v1/security/settings Security settings
PUT /api/v1/security/settings Update security settings
GET /api/v1/swap Swap information
POST /api/v1/swap Adjust Swap
POST /api/v1/batch-create Batch create containers
POST /api/v1/batch-action Batch power action, delete, or reinstall
POST /api/v1/ssh-ticket Create WebSSH ticket
POST /api/v1/vnc-ticket Create WebVNC ticket

Accounts and Logs

Method Path Description
POST /api/v1/sub-user/create Create sub-user link
GET /api/v1/sub-users Sub-user list
POST /api/v1/sub-users/{id}/rotate-password Rotate sub-user password
GET /api/v1/sub-users/{id}/audit-logs Sub-user audit logs
GET /api/v1/sub-users/{id}/login-logs Sub-user login logs
GET /api/v1/audit-logs Audit logs
GET /api/v1/login-logs Login logs
GET /api/v1/api-keys API key list
POST /api/v1/api-keys Create API key
PATCH /api/v1/api-keys/{id} Update API key
DELETE /api/v1/api-keys/{id} Delete API key

Response Samples

The samples below are grouped by endpoint path. Resource numbers, task IDs, container IDs, timestamps, IP addresses, and keys will differ in real environments. Passwords, tickets, and API keys are masked.

Overview

{
  "GET /api/v1/dashboard": {
    "success": true,
    "data": {
      "running": 31,
      "stopped": 0,
      "total_containers": 31
    }
  },
  "GET /api/v1/host-info": {
    "success": true,
    "data": {
      "cpu": { "cores": 8, "usage_pct": 1.16 },
      "ram": { "total_mb": 31825, "used_mb": 1275, "free_mb": 30550 },
      "disk": { "total_gb": 1750.49, "used_gb": 123.98, "free_gb": 1626.51 },
      "network": {
        "public_ipv4": "203.0.113.10",
        "public_ipv4_interface": "eth0",
        "public_ipv6": "2001:db8:100::2",
        "public_ipv6_interface": "eth0"
      },
      "load": { "load1": 0.01, "load5": 0.03, "load15": 0.01 }
    }
  },
  "GET /api/v1/routing": {
    "success": true,
    "data": {
      "nat4": { "used": 62, "remaining": "45474", "total": "45536" },
      "ipv4": { "used": 1, "remaining": "3", "total": "4" },
      "ipv6": { "used": 31, "remaining": "large", "total": "large" },
      "public_ipv4_addresses": [
        { "address": "203.0.113.10", "interface": "eth0", "prefix_len": 32, "gateway": "203.0.113.1" }
      ],
      "ipv4_assignments": [
        { "container_id": 5, "container_name": "example-vm", "address": "203.0.113.10", "interface": "eth0", "prefix_len": 32, "gateway": "203.0.113.1" }
      ],
      "nat4_mappings": [
        { "container_id": 5, "container_name": "example-vm", "status": "running", "ip": "10.0.0.10", "host_port": 22004, "container_port": 22, "protocol": "tcp" }
      ],
      "ipv6_assignments": [
        { "container_id": 5, "container_name": "example-vm", "address": "2001:db8:100::1005", "prefix_len": 64, "interface": "eth0" }
      ]
    }
  },
  "PUT /api/v1/routing": {
    "success": true,
    "data": {
      "ipv4": { "used": 1, "remaining": "3", "total": "4" },
      "public_ipv4_addresses": [
        { "address": "203.0.113.10", "interface": "eth0", "prefix_len": 32, "gateway": "203.0.113.1" }
      ],
      "ipv6_prefixes": [
        { "interface": "eth0", "address": "2001:db8:100::2", "prefix": "2001:db8:100::/64", "prefix_len": 64, "gateway": "2001:db8:100::1" }
      ]
    }
  },
  "POST /api/v1/routing/ipv4-scan": {
    "success": true,
    "data": [
      { "address": "203.0.113.10", "interface": "eth0", "prefix_len": 32, "gateway": "203.0.113.1", "status": "available", "usable": true, "reason": "" }
    ]
  },
  "GET /api/v1/ipv6/status": {
    "success": true,
    "data": {
      "available": true,
      "reachable": true,
      "reason": "usable public IPv6 prefix detected",
      "prefixes": [
        { "interface": "eth0", "address": "2001:db8:100::2", "prefix": "2001:db8:100::/64", "prefix_len": 64, "gateway": "2001:db8:100::1" }
      ]
    }
  },
  "GET /api/v1/tasks": {
    "success": true,
    "data": []
  },
  "DELETE /api/v1/tasks/{task_id}": {
    "success": true,
    "message": "Task deleted"
  }
}

Containers

{
  "GET /api/v1/containers": {
    "success": true,
    "data": [
      {
        "id": 5,
        "uuid": "00000000-0000-4000-8000-000000000005",
        "name": "example-vm",
        "virtualization": "lxc",
        "template": "debian-bullseye",
        "vcpu": 1,
        "ram_mb": 512,
        "disk_gb": 10,
        "status": "running",
        "ip": "10.0.0.10",
        "ipv6": "2001:db8:100::1005",
        "ssh_port": 22004,
        "ssh_password": "***",
        "port_mappings": [
          { "container_port": 22, "host_port": 22004, "protocol": "tcp", "description": "SSH" },
          { "container_port": 20000, "host_port": 20000, "protocol": "tcp", "description": "Port-20000" }
        ]
      }
    ]
  },
  "POST /api/v1/containers/list": {
    "success": true,
    "data": [
      { "id": 5, "uuid": "00000000-0000-4000-8000-000000000005", "name": "example-vm", "status": "running", "ip": "10.0.0.10" }
    ]
  },
  "POST /api/v1/containers": {
    "success": true,
    "message": "Container created successfully"
  },
  "GET /api/v1/containers/{id|uuid|name}": {
    "success": true,
    "data": {
      "id": 5,
      "uuid": "00000000-0000-4000-8000-000000000005",
      "name": "example-vm",
      "status": "running",
      "ip": "10.0.0.10",
      "ipv6": "2001:db8:100::1005",
      "ssh_port": 22004,
      "ssh_password": "***",
      "policy_blocked": false
    }
  },
  "POST /api/v1/containers/{id}/start": {
    "success": true,
    "message": "Task queued",
    "data": { "task_id": "task-10", "container_name": "example-vm", "status": "pending", "action": "start" }
  },
  "POST /api/v1/containers/{id}/stop": {
    "success": true,
    "message": "Task queued",
    "data": { "task_id": "task-10", "container_name": "example-vm", "status": "pending", "action": "stop" }
  },
  "POST /api/v1/containers/{id}/restart": {
    "success": true,
    "message": "Task queued",
    "data": { "task_id": "task-10", "container_name": "example-vm", "status": "pending", "action": "restart" }
  },
  "POST /api/v1/containers/{id}/reinstall": {
    "success": true,
    "message": "Task queued",
    "data": { "task_id": "task-10", "container_name": "example-vm", "status": "pending", "action": "reinstall" }
  },
  "DELETE /api/v1/containers/{id}/delete": {
    "success": true,
    "message": "Task queued",
    "data": { "task_id": "task-10", "container_name": "example-vm", "status": "pending", "action": "delete" }
  },
  "GET /api/v1/containers/{id}/usage": {
    "success": true,
    "data": {
      "cpu_usage_pct": 0,
      "cpu_usage_usec": 3908852,
      "memory_usage_bytes": 29331456,
      "disk_usage_bytes": 515100672,
      "network_rx_bytes": 131232,
      "network_tx_bytes": 16828,
      "load1": 0.1,
      "load5": 0.06,
      "load15": 0.01
    }
  },
  "GET /api/v1/containers/{id}/traffic": {
    "success": true,
    "data": {
      "mode": "total",
      "limit_gb": 0,
      "in_limit_gb": 0,
      "out_limit_gb": 0,
      "total_used_bytes": 142082,
      "rx_used_bytes": 127212,
      "tx_used_bytes": 14870,
      "used_pct": 0,
      "reset_date": "2026-06"
    }
  },
  "POST /api/v1/containers/{id}/traffic-reset": {
    "success": true,
    "message": "Traffic reset"
  },
  "PUT /api/v1/containers/{id}/traffic-limit": {
    "success": true,
    "message": "Traffic limit updated"
  },
  "PUT /api/v1/containers/{id}/resource-limit": {
    "success": true,
    "message": "Resource limits updated"
  },
  "PUT /api/v1/containers/{id}/expiry": {
    "success": true,
    "message": "Expiry updated"
  },
  "POST /api/v1/containers/{id}/reset-password": {
    "success": true,
    "message": "SSH password reset successfully",
    "data": { "password": "***" }
  },
  "POST /api/v1/containers/{id}/ipv6": {
    "success": true,
    "message": "IPv6 assigned",
    "data": { "id": 5, "name": "example-vm", "ipv6": "2001:db8:100::1005" }
  }
}

Ports and Snapshots

{
  "GET /api/v1/containers/{id}/random-port": {
    "success": true,
    "data": { "port": 61320 }
  },
  "POST /api/v1/containers/{id}/port-mappings": {
    "success": true,
    "data": [
      { "container_port": 22, "host_port": 22004, "protocol": "tcp", "description": "SSH" },
      { "container_port": 8080, "host_port": 61320, "protocol": "tcp", "description": "HTTP" }
    ]
  },
  "PUT /api/v1/containers/{id}/port-mappings/{index}": {
    "success": true,
    "data": [
      { "container_port": 8081, "host_port": 61320, "protocol": "tcp", "description": "HTTP" }
    ]
  },
  "DELETE /api/v1/containers/{id}/port-mappings/{index}": {
    "success": true,
    "data": []
  },
  "GET /api/v1/snapshots": {
    "success": true,
    "data": null
  },
  "GET /api/v1/containers/{id}/snapshots": {
    "success": true,
    "data": {
      "quota": 1,
      "schedule": { "enabled": false, "interval_hours": 0, "last_run": "", "next_run": "", "time": "", "created_by": "" },
      "snapshots": []
    }
  },
  "POST /api/v1/containers/{id}/snapshots": {
    "success": true,
    "data": {
      "id": "snap-20260608-001",
      "container_id": 5,
      "container_name": "example-vm",
      "created_at": "2026-06-08 16:00:00",
      "created_by": "api:Automation",
      "scheduled": false,
      "size_bytes": 10485760
    }
  },
  "DELETE /api/v1/containers/{id}/snapshots/{snapshot_id}": {
    "success": true,
    "message": "Snapshot deleted"
  },
  "POST /api/v1/containers/{id}/snapshots/{snapshot_id}/restore": {
    "success": true,
    "message": "Snapshot restored"
  },
  "POST /api/v1/containers/{id}/snapshots/schedule": {
    "success": true,
    "data": {
      "container": { "id": 5, "name": "example-vm", "snapshot_schedule_enabled": true, "snapshot_schedule_interval_hours": 24, "snapshot_schedule_time": "03:00" }
    }
  },
  "PUT /api/v1/containers/{id}/snapshots/quota": {
    "success": true,
    "data": {
      "quota": 2,
      "container": { "id": 5, "name": "example-vm", "snapshot_limit": 2 }
    }
  }
}

Platform Management

{
  "GET /api/v1/templates": {
    "success": true,
    "data": [
      { "id": "ubuntu-noble", "name": "Ubuntu 24.04", "distro": "ubuntu", "release": "noble", "arch": "amd64", "description": "Ubuntu 24.04 LTS" },
      { "id": "debian-bookworm", "name": "Debian 12", "distro": "debian", "release": "bookworm", "arch": "amd64", "description": "Debian 12 (Bookworm)" }
    ]
  },
  "GET /api/v1/images": {
    "success": true,
    "data": [
      { "id": "ubuntu-noble", "name": "Ubuntu 24.04", "type": "lxc", "downloaded": true, "enabled": true, "downloading": false, "progress": 0, "size_bytes": 135005452 }
    ]
  },
  "POST /api/v1/images/download": {
    "success": true,
    "message": "Already downloaded"
  },
  "POST /api/v1/images/cancel": {
    "success": true,
    "message": "Cancel requested"
  },
  "DELETE /api/v1/images/delete": {
    "success": true,
    "message": "Deleted"
  },
  "PUT /api/v1/images/toggle": {
    "success": true,
    "message": "OK"
  },
  "GET /api/v1/security/alerts": {
    "success": true,
    "data": []
  },
  "POST /api/v1/security/check": {
    "success": true,
    "message": "Security check completed"
  },
  "GET /api/v1/security/logs?container={name}": {
    "success": true,
    "data": []
  },
  "GET /api/v1/security/summary": {
    "success": true,
    "data": { "critical": 0, "high": 0, "medium": 0, "low": 0, "total_alerts": 0 }
  },
  "GET /api/v1/security/settings": {
    "success": true,
    "data": { "auto_shutdown": false }
  },
  "PUT /api/v1/security/settings": {
    "success": true,
    "data": { "auto_shutdown": false }
  },
  "GET /api/v1/swap": {
    "success": true,
    "data": { "total_mb": 16383, "used_mb": 0, "free_mb": 16383, "enabled": true, "swap_file": "/swapfile" }
  },
  "POST /api/v1/swap": {
    "success": true,
    "message": "SWAP 已调整为 16384 MB",
    "data": { "total_mb": 16383, "used_mb": 0, "free_mb": 16383, "enabled": true, "swap_file": "/swapfile" }
  },
  "POST /api/v1/batch-create": {
    "success": true,
    "data": ["task-12"]
  },
  "POST /api/v1/batch-action": {
    "success": true,
    "data": ["task-13"]
  },
  "POST /api/v1/ssh-ticket": {
    "success": true,
    "data": { "ticket": "***60 seconds valid***" }
  },
  "POST /api/v1/vnc-ticket": {
    "success": true,
    "data": { "ticket": "***60 seconds valid***" }
  }
}

Accounts and Logs

{
  "POST /api/v1/sub-user/create": {
    "success": true,
    "message": "Sub-user created",
    "data": {
      "id": "sub-xxxxxxxx",
      "username": "user-xxxxxxxx",
      "password": "***",
      "container_names": ["example-vm"],
      "access_code": "********",
      "created_at": "2026-06-08 16:00:00"
    }
  },
  "GET /api/v1/sub-users": {
    "success": true,
    "data": []
  },
  "POST /api/v1/sub-users/{id}/rotate-password": {
    "success": true,
    "data": { "username": "user-xxxxxxxx", "password": "***", "access_code": "********" }
  },
  "GET /api/v1/sub-users/{id}/audit-logs": {
    "success": true,
    "data": []
  },
  "GET /api/v1/sub-users/{id}/login-logs": {
    "success": true,
    "data": []
  },
  "GET /api/v1/audit-logs": {
    "success": true,
    "data": [
      { "time": "2026-06-08 15:44:40", "action": "apikey.create", "target": "Test", "detail": "scopes=*", "user": "admin", "success": true }
    ]
  },
  "GET /api/v1/login-logs": {
    "success": true,
    "data": [
      { "time": "2026-06-08 08:24:00 UTC", "username": "admin", "ip": "198.51.100.23", "user_agent": "Mozilla/5.0 ...", "success": true }
    ]
  },
  "GET /api/v1/api-keys": {
    "success": true,
    "data": [
      { "id": "c271023f", "name": "Test", "prefix": "clicd_sk_dd9d...", "ip_whitelist": "", "created_at": "2026-06-08 15:44:40", "last_used": "2026-06-08 15:46:10", "scopes": ["*"], "last_used_ip": "198.51.100.23" }
    ]
  },
  "POST /api/v1/api-keys": {
    "success": true,
    "message": "API key created. Save this key now - it won't be shown again.",
    "data": { "id": "a1b2c3d4", "name": "Automation", "key": "clicd_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "prefix": "clicd_sk_xxxx...", "scopes": ["dashboard:read", "container:read"] }
  },
  "PATCH /api/v1/api-keys/{id}": {
    "success": true,
    "data": { "id": "a1b2c3d4", "name": "Automation", "prefix": "clicd_sk_xxxx...", "scopes": ["dashboard:read", "container:read"], "disabled": false }
  },
  "DELETE /api/v1/api-keys/{id}": {
    "success": true,
    "message": "API key deleted"
  }
}