使用指南,从注册到排障

使用指南 /开放 API 与集成 /面板开放 API:用脚本管理站点

面板开放 API:用脚本管理站点

发布于 2026-11-09 21:12:34 约 3849 字 约 10 分钟读完

面板开放 API:用脚本管理站点

面板提供一组 REST 接口,可以把站点与服务器信息接到自己的脚本、CI/CD、监控或计费系统里,也可以批量创建、删除站点。接口与面板共用同一个服务端口,使用 API Key 鉴权。

接入信息

项目值
接口地址http://<面板地址>:8888/api/v1
鉴权X-API-Key: <你的密钥>
请求格式GET 用查询参数;POST 用 application/x-www-form-urlencoded(不是 JSON)
响应格式application/json;成功直接返回数据对象,失败返回 {"error":"...","code":403}
前置条件面板已绑定账号,且当前授权在有效期内

创建 API 密钥

  1. 进入面板「API 密钥」→「新建密钥」;
  2. 勾选权限范围(scope),按最小权限原则只给需要的;
  3. 可设置有效期与备注。密钥只在创建时完整显示一次,请立即保存到密码管理器。

密钥以哈希形式存储,面板不保存明文;可选范围还会受当前套餐约束,套餐未开放的能力不会出现在勾选项里。怀疑泄露时停用或删除密钥即可立即失效。

权限范围(scope)

scope对应接口用途
system:readGET /api/v1/system主机名、面板版本、CPU / 内存 / 磁盘占用、站点数
sites:readGET /api/v1/sites、GET /api/v1/site/get站点列表与单个站点详情(含已绑定域名)
sites:createPOST /api/v1/site/create新建站点
sites:deletePOST /api/v1/site/delete删除站点及其域名、文件目录(不可恢复)
plan:readGET /api/v1/plan当前套餐的配额与可用功能,用于按版本适配脚本

接口说明

方法路径参数返回
GET/api/v1/sites—{"sites":[...],"count":N}
GET/api/v1/site/getname 站点名{"site":{...},"domains":["..."]}
GET/api/v1/system—主机名、版本、CPU / 内存 / 磁盘、站点数
GET/api/v1/plan—plan、quotas、features、api_scopes、vhost_count 等
POST/api/v1/site/createname、passwd,可选 type / runtime / web_quota / db_quota / max_connect / speed_limit / max_subdir / cron_count创建结果
POST/api/v1/site/deletename 站点名删除结果

创建站点时 name 为 3–32 位小写字母、数字、- 或 _,passwd 为 6–64 位。资源额度超过套餐上限会自动收口到上限;站点级功能开关不允许通过 API 覆盖;系统站点不允许删除。

curl 示例

# 站点列表
curl -s http://82.157.137.169:8888/api/v1/sites \
  -H "X-API-Key: $NC_API_KEY"

# 服务器信息
curl -s http://82.157.137.169:8888/api/v1/system \
  -H "X-API-Key: $NC_API_KEY"

# 单个站点
curl -s "http://82.157.137.169:8888/api/v1/site/get?name=demo01" \
  -H "X-API-Key: $NC_API_KEY"

# 新建站点(表单编码,不是 JSON)
curl -s -X POST http://82.157.137.169:8888/api/v1/site/create \
  -H "X-API-Key: $NC_API_KEY" \
  -d "name=demo01" \
  -d "passwd=StrongPass123" \
  -d "runtime=php"

# 删除站点(不可恢复)
curl -s -X POST http://82.157.137.169:8888/api/v1/site/delete \
  -H "X-API-Key: $NC_API_KEY" \
  -d "name=demo01"

PHP 示例

<?php
$base = 'http://82.157.137.169:8888';
$key  = getenv('NC_API_KEY');

function ncApi($base, $key, $method, $path, array $data = []) {
    $url = $base . $path;
    $ch  = curl_init();
    if ($method === 'GET' && $data) {
        $url .= '?' . http_build_query($data);
    }
    curl_setopt_array($ch, [
        CURLOPT_URL            => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ['X-API-Key: ' . $key],
        CURLOPT_CUSTOMREQUEST  => $method,
    ]);
    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    }
    $body = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return [$code, json_decode($body, true)];
}

[$code, $res] = ncApi($base, $key, 'GET', '/api/v1/sites');
if ($code !== 200) {
    fwrite(STDERR, ($res['error'] ?? 'request failed') . "\n");
    exit(1);
}
foreach ($res['sites'] as $site) {
    echo $site['name'], "\t", $site['domain'], "\n";
}

Node.js 示例

const base = 'http://82.157.137.169:8888';
const key  = process.env.NC_API_KEY;

async function ncApi(method, path, data = null) {
  const url = new URL(base + path);
  const opt = { method, headers: { 'X-API-Key': key } };
  if (method === 'POST') {
    opt.body = new URLSearchParams(data);
  } else if (data) {
    for (const [k, v] of Object.entries(data)) url.searchParams.set(k, v);
  }
  const resp = await fetch(url, opt);
  const body = await resp.json();
  if (!resp.ok) throw new Error(`${resp.status} ${body.error}`);
  return body;
}

const { count, sites } = await ncApi('GET', '/api/v1/sites');
console.log(count, sites.map((s) => s.name));

错误码

状态码含义
401API Key 无效、已停用或已过期
403密钥缺少对应 scope;面板未绑定账号;授权已过期;系统站点不可删除
404接口或站点不存在
400缺少必填参数,或参数格式不合法

安全建议

  • 密钥只放在环境变量或密钥管理服务里,不要写进前端代码、公开仓库或截图;
  • 按最小权限创建多个密钥,按用途区分,便于单独吊销;
  • 接口尽量走 HTTPS 或只在内网调用,避免明文密钥在公网传输;
  • 删除类接口请先在测试站点验证,删除后文件和数据库不会进入回收站。