开发者 API

用一把 API Key 读取自己账号的状态、套餐、用量和设备,适合接进你自己的脚本或面板。 节点清单与取配置需要单独授权,不在这份公开文档里。

Base URL https://clash.cupzz.cn/api/v1 下载这份文档(Markdown)

认证

每个请求带上 Authorization 头,值是 Bearer 加一个空格,再加你的 API Key:

curl https://clash.cupzz.cn/api/v1/ext/account \
  -H "Authorization: Bearer cncp_你的密钥"
API Key 从哪来

由站点管理员发放:可以单独发给你,也可能随你购买的套餐附带。 它只在生成的那一刻显示一次,之后谁也查不回来(服务端只存哈希)。 如果丢了,请管理员重新生成一把。

还需要「允许 API 使用」的套餐

光有 Key 还不够:你的账号名下必须至少有一档允许 API 使用的生效套餐。 站点可以在套餐模板上开关这一项,而注册赠送的免费套餐默认不允许。 没有这样的套餐时,所有接口都返回 403 与错误码 api_plan_required(这种调用不会消耗配额)。

站点可能整体关掉了 API

站长可以一键关闭对外 API。这时所有 /api/v1/ext/* 调用返回 403 与 api_disabled,与你的 Key 是否有效无关。 遇到这个错误码请联系站长,换一把 Key 没有用。

保管好它

API Key 等同于你的账号访问权。不要写进前端代码、不要提交到公开仓库、 不要贴进聊天群。怀疑泄露时请管理员立即停用。

配额

每次调用消耗一次配额(包括查询配额本身)。配额有两种模式,由管理员设置:

模式含义什么时候恢复
total 总共 N 次,用完为止 不恢复(需要管理员调整)
period 每个周期 N 次 到下一个周期自动重置(按天/周/月/季/年)

剩余次数、下次重置时间随时可以在 用量接口 里查到。 配额用尽时接口返回 429 与错误码 api_quota_exceeded。

接口

下面这些都需要 API Key。响应统一是 {"ok":true,"data":…} 的信封。

节点相关接口不在本页

节点清单与取配置这两个接口会返回真实节点信息,只对单独授权过的 Key 开放, 因此不写进公开文档。需要对接时联系站长单独开通。

GET /api/v1/ext/account

账号概览:状态、设备数、以及名下所有套餐(含到期、用量、能否连接)。

{
  "ok": true,
  "data": {
    "accountId": "you@example.com",
    "email": "you@example.com",
    "qq": "12345678",
    "status": "active",
    "createdAt": 1792064568,
    "deviceLimit": 2,
    "devices": 1,
    "plans": [
      {
        "grantId": "g_xxxxxxxxxx",
        "title": "标准套餐",
        "planName": "standard",
        "serviceStatus": "normal",
        "expiresAt": 1794656567,
        "remainingDays": 30,
        "trafficLimit": 107374182400,
        "usedBytes": 21474836480,
        "remainingBytes": 85899345920,
        "deviceLimit": 2,
        "canConnect": true,
        "denyReason": ""
      }
    ],
    "traffic": { "unlimited": false, "limitBytes": 107374182400, "usedBytes": 21474836480, "remainingBytes": 85899345920 },
    "expiry": { "expiresAt": 1794656567, "remainingDays": 30 },
    "invite": {
      "enabled": true,
      "code": "A1B2C3D4",
      "link": "https://clash.cupzz.cn/register?invite=A1B2C3D4",
      "invitedCount": 3,
      "notice": "",
      "inviterReward": "每邀请 1 人:+10 GB 流量",
      "inviteeReward": "被邀请注册:+5 GB 流量"
    }
  }
}  

canConnect 为 false 时 denyReason 会说明原因 (到期 / 流量用尽 / 被停用等)。流量单位是字节。 traffic 与 expiry 是整个账号的汇总(多条套餐相加; 有任意一条不限流量时 unlimited 为 true 且两个额度字段为 -1, expiry 取最近到期的那条,那才是"什么时候会断")。

POST /api/v1/ext/query/code

给目标账号的邮箱发一个查询验证码。邮箱由服务端配置的发件邮箱发出, 你无法指定发件人。响应永远是同一句话(不暴露该邮箱是否在本站注册过)。

curl -X POST https://clash.cupzz.cn/api/v1/ext/query/code \
  -H "Authorization: Bearer cncp_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com"}'
{"ok":true,"data":{"sent":true,"message":"如果该邮箱已注册,验证码已发出。","serverTime":1792064613}}

站点没有开启邮箱验证码时返回 403:这条路径不会被悄悄放行, 因为那等于开了一个不需要凭据的账号查询入口。

POST /api/v1/ext/query

查询指定账号(不只是你自己的)。必须出示目标账号的密码或上面那个验证码, 两者给其一即可。返回的内容与 账号接口 完全一致。

curl -X POST https://clash.cupzz.cn/api/v1/ext/query \
  -H "Authorization: Bearer cncp_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"该账号的密码"}'

# 或者用验证码:
curl -X POST https://clash.cupzz.cn/api/v1/ext/query \
  -H "Authorization: Bearer cncp_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","code":"123456"}'

凭据不对与"该邮箱没有账号"返回完全相同的响应 (401 unauthorized),失败次数与网页登录共用同一套限速, 换个入口多试几次是不行的。验证码一次性、有有效期,且只发给已注册的邮箱。

GET /api/v1/ext/devices

自己账号下的设备列表。

{
  "ok": true,
  "data": {
    "devices": [
      {
        "deviceId": "d_1a2b3c…",
        "name": "我的手机",
        "platform": "android",
        "status": "active",
        "createdAt": 1792064568,
        "lastSeenAt": 1792064600
      }
    ]
  }
}
POST /api/v1/ext/devices/register

登记一台设备。登记后会自动绑定到你的账号并激活(受设备数上限约束, 与客户端登录时的规则一致)。

curl -X POST https://clash.cupzz.cn/api/v1/ext/devices/register \
  -H "Authorization: Bearer cncp_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{
    "deviceId": "d_你的设备标识",
    "publicKey": "base64 编码的 X25519 公钥",
    "keyId": "k1_公钥指纹",
    "name": "我的脚本"
  }'
{"ok":true,"data":{"deviceId":"d_…","status":"active","created":true,"serverTime":1792064568}}

deviceId 与 publicKey 必填;keyId、 name 可选。公钥用于加密下发给该设备的配置。

POST /api/v1/ext/devices/remove

移除自己账号下的一台设备,该设备的登录状态会立刻失效。

curl -X POST https://clash.cupzz.cn/api/v1/ext/devices/remove \
  -H "Authorization: Bearer cncp_你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"deviceId":"d_要移除的设备"}'
{"ok":true,"data":{"removed":true}}
GET /api/v1/ext/usage

这把 Key 的配额与最近的调用统计(按天聚合)。

{
  "ok": true,
  "data": {
    "keyPrefix": "cncp_a1b2c3",
    "label": "给对账脚本用",
    "quotaMode": "period",
    "quotaPeriod": "month",
    "quotaLimit": 10000,
    "used": 42,
    "remaining": 9958,
    "resetAt": 1794742968,
    "expiresAt": 0,
    "lastUsedAt": 1792064613,
    "calls": [
      { "day": "2026-10-15", "endpoint": "/api/v1/ext/account", "calls": 12 }
    ],
    "serverTime": 1792064613
  }
}

remaining 为 -1 表示不限次数; resetAt 为 0 表示没有"重置"这回事(total 模式)。

公开接口(不需要 Key)

GET /api/v1/stats

站点实时统计,客户端底部那条数据用的就是它。

{"ok":true,"data":{"onlineUsers":12,"todayConnections":378,"totalConnections":9723}}
GET /api/v1/meta

站点配置:名称、公告、下载地址、联系方式、版本要求等。

错误

失败时返回非 2xx 状态码,响应体是同一个信封形状:

{"ok":false,"error":{"code":"unauthorized","message":"登录状态无效或已过期。"}}
HTTPcode含义与下一步
401unauthorized Key 无效、被停用或已过期。找管理员确认。
429api_quota_exceeded 配额用尽。等下个周期自动恢复,或让管理员提高额度。
403forbidden 这个 Key 不能做这件事(例如用设备令牌调 Key 专属接口)。
403account_disabled 账号被停用,Key 一并失效。
403api_disabled 站长把整站的对外 API 关掉了。这跟你的 Key 无关,换 Key 也没用,需要联系站长。
403api_plan_required 名下没有「允许 API 使用」的生效套餐(注册赠送的免费套餐默认不允许)。 这种调用不消耗配额;需要开通支持 API 的套餐。
400invalid_request 请求参数不对,看 message 里的说明。
404not_found 目标不存在(例如要移除的设备不在你的账号下)。