docs: vendor the documentation site into the monorepo

Fold the standalone 3x-ui-docs project (Next.js 16 + Fumadocs, deployed to
docs.sanaei.dev) into docs/ so the panel and its documentation share a single
source of truth, the way sing-box keeps its docs in-tree. The old repo becomes
redundant and can be retired.

- Import the full site under docs/ (app, components, content, lib, public,
  scripts, config). The self-contained pnpm project sits alongside the existing
  engineering notes with no filename collisions.
- Re-point "Edit on GitHub" links from MHSanaei/3x-ui-docs to this repo's
  docs/content/docs path (docs/lib/shared.ts, docs/app/.../page.tsx).
- Add docs-ci.yml and docs-deploy.yml under .github/workflows/, scoped to
  docs/** and run with working-directory: docs, since GitHub only runs
  workflows from the repo-root .github/. deploy-static.yml's GitHub Pages
  publish (CNAME docs.sanaei.dev) carries over unchanged.

Follow-up (outside this commit): attach the docs.sanaei.dev custom domain to
this repository's Pages (or set the Vercel project's root directory to docs),
confirm the site is live from the monorepo, then delete MHSanaei/3x-ui-docs.
This commit is contained in:
MHSanaei
2026-07-07 23:07:14 +02:00
parent 2c49dbf54e
commit 9b91f0f42e
283 changed files with 44179 additions and 0 deletions
@@ -0,0 +1,75 @@
---
title: API 令牌
description: >-
管理用于程序化认证的 Bearer 令牌(机器人、代表本节点操作的中心面板、CI)。每个令牌都有唯一的名称和一个启用标志——禁用即可在不删除的情况下吊销,删除则为永久吊销。令牌以
SHA-256 哈希形式存储,明文仅在创建响应中返回一次——此后无法再次获取,因此请当场复制保存。在任意 /panel/api/* 请求中以
<code>Authorization: Bearer &lt;token&gt;</code> 的形式发送令牌——该令牌是一份完全管理员凭据。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
List every API token, enabled or not. The token value is never returned
— only metadata.
url: >-
#list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
- depth: 2
title: >-
Mint a new API token. Name must be unique and 1-64 characters; the token
string is server-generated and returned only in this response — it is
stored hashed and cannot be retrieved later.
url: >-
#mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
- depth: 2
title: >-
Permanently delete a token. Any caller using it stops authenticating
immediately.
url: >-
#permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
- depth: 2
title: >-
Toggle a token enabled/disabled without deleting it. Disabled tokens are
rejected by checkAPIAuth on the next request.
url: >-
#toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
structuredData:
headings:
- content: >-
List every API token, enabled or not. The token value is never
returned — only metadata.
id: >-
list-every-api-token-enabled-or-not-the-token-value-is-never-returned--only-metadata
- content: >-
Mint a new API token. Name must be unique and 1-64 characters; the
token string is server-generated and returned only in this response —
it is stored hashed and cannot be retrieved later.
id: >-
mint-a-new-api-token-name-must-be-unique-and-1-64-characters-the-token-string-is-server-generated-and-returned-only-in-this-response--it-is-stored-hashed-and-cannot-be-retrieved-later
- content: >-
Permanently delete a token. Any caller using it stops authenticating
immediately.
id: >-
permanently-delete-a-token-any-caller-using-it-stops-authenticating-immediately
- content: >-
Toggle a token enabled/disabled without deleting it. Disabled tokens
are rejected by checkAPIAuth on the next request.
id: >-
toggle-a-token-enableddisabled-without-deleting-it-disabled-tokens-are-rejected-by-checkapiauth-on-the-next-request
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/apiTokens","method":"get"},{"path":"/panel/api/setting/apiTokens/create","method":"post"},{"path":"/panel/api/setting/apiTokens/delete/{id}","method":"post"},{"path":"/panel/api/setting/apiTokens/setEnabled/{id}","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,72 @@
---
title: 身份验证
description: >-
支持两种身份验证模式。UI 会话使用登录端点设置的 Cookie。程序化客户端(机器人、脚本、远程面板)则使用从“设置 →
安全 → API Token”获取的 Bearer token 进行身份验证。两者都适用于 /panel/api/* 下的所有端点。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
Authenticate with username + password and receive a session cookie.
Required before any cookie-based API call.
url: >-
#authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
- depth: 2
title: Clear the session cookie. Requires the CSRF header for browser sessions.
url: '#clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions'
- depth: 2
title: >-
Mint a CSRF token for the current session. The SPA replays it in the
X-CSRF-Token header on unsafe requests. Bearer-token callers can skip
this — the middleware short-circuits CSRF for authenticated API
requests.
url: >-
#mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
- depth: 2
title: >-
Returns whether 2FA is enabled on the panel — used by the login page to
decide whether to show the OTP field.
url: >-
#returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
structuredData:
headings:
- content: >-
Authenticate with username + password and receive a session cookie.
Required before any cookie-based API call.
id: >-
authenticate-with-username--password-and-receive-a-session-cookie-required-before-any-cookie-based-api-call
- content: >-
Clear the session cookie. Requires the CSRF header for browser
sessions.
id: clear-the-session-cookie-requires-the-csrf-header-for-browser-sessions
- content: >-
Mint a CSRF token for the current session. The SPA replays it in the
X-CSRF-Token header on unsafe requests. Bearer-token callers can skip
this — the middleware short-circuits CSRF for authenticated API
requests.
id: >-
mint-a-csrf-token-for-the-current-session-the-spa-replays-it-in-the-x-csrf-token-header-on-unsafe-requests-bearer-token-callers-can-skip-this--the-middleware-short-circuits-csrf-for-authenticated-api-requests
- content: >-
Returns whether 2FA is enabled on the panel — used by the login page
to decide whether to show the OTP field.
id: >-
returns-whether-2fa-is-enabled-on-the-panel--used-by-the-login-page-to-decide-whether-to-show-the-otp-field
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/login","method":"post"},{"path":"/logout","method":"post"},{"path":"/csrf-token","method":"get"},{"path":"/getTwoFactorEnable","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,35 @@
---
title: 备份
description: 与已配置的 Telegram 机器人进行交互的操作。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
向每个配置为管理员接收方的 Telegram 聊天发送一份最新的数据库备份。无请求体,无参数。
url: >-
#send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
structuredData:
headings:
- content: >-
向每个配置为管理员接收方的 Telegram 聊天发送一份最新的数据库备份。无请求体,无参数。
id: >-
send-a-fresh-db-backup-to-every-telegram-chat-configured-as-an-admin-recipient-no-body-no-params
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/backuptotgbot","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,511 @@
---
title: 客户端
description: >-
将客户端作为一等实体进行管理,可将其挂载到一个或多个入站。单条客户端记录会驱动其所属
每个入站中的 settings.clients 条目。相关端点位于 /panel/api/clients 之下。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
列出每个客户端及其挂载的入站 ID 和流量记录。reverse 字段若已设置,将以嵌套 JSON
对象的形式返回(写入时仍接受旧版的 JSON 编码字符串形式)。
url: >-
#list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
- depth: 2
title: >-
在服务端对客户端进行筛选、排序和分页。每一项都是精简记录(不含
uuid/password/auth/flow/security/reverse/tgId),因此客户端页面只需几 KB
即可承载约 25 行,而无需返回整张表。响应中还包含一个基于完整数据库行集计算的汇总,
这样在用户分页或筛选时仪表盘计数器仍保持稳定。每页上限为 200;可调用 /get/:email
获取某个客户端用于编辑/信息弹窗的完整载荷。
url: >-
#filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
- depth: 2
title: >-
按 email 获取单个客户端,包括它所挂载的入站 ID 和外部配置 ID。
url: >-
#fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
- depth: 2
title: >-
在一次调用中创建一个新客户端并将其挂载到一个或多个入站。请求体为 JSON。各协议的密钥
VLESS/VMess 的 UUID、Trojan/Shadowsocks 的 password、Hysteria 的 auth)在
省略时由服务端生成,因此调用方只需发送通用字段。
url: >-
#create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
- depth: 2
title: >-
按 email 更新现有客户端。变更会传播到每个挂载的入站。请求体为 JSON 客户端载荷——
请提供你希望保留的完整字段集(服务端会替换整条记录,而非局部更新)。
url: >-
#update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
- depth: 2
title: >-
按 email 删除客户端。将其从每个挂载的入站中移除,并删除其流量记录,除非传入
keepTraffic=1。
url: >-
#delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
- depth: 2
title: >-
将现有客户端挂载到一个或多个额外的入站。请求体为 JSON。
url: >-
#attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
- depth: 2
title: 在不删除客户端的前提下,将其从一个或多个入站上分离。
url: '#detach-a-client-from-one-or-more-inbounds-without-deleting-the-client'
- depth: 2
title: >-
替换某客户端的外部链接(在其订阅中呈现的按客户端分享链接和远程订阅 URL)。发送完整
集合;服务端会替换所有记录。
url: >-
#replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
- depth: 2
title: >-
全局重置每个客户端的上行/下行计数器。配额和到期时间不受影响。若有任何计数器实际发生
变动,则触发一次 Xray 重启。
url: >-
#reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
- depth: 2
title: >-
删除所有流量配额已耗尽(在禁用重置时,used >= total)或已过期的客户端。返回删除
数量,并在任一客户端位于运行中的入站时触发一次 Xray 重启。
url: >-
#delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
- depth: 2
title: >-
删除所有未挂载到任何入站的客户端,连同其流量记录、IP 日志和外部链接一并删除。适用于
清理在其入站被移除后处于未挂载状态的客户端。返回删除数量。无法撤销。
url: >-
#delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
- depth: 2
title: >-
以 {client, inboundIds} 数组的形式返回每个客户端——与 /bulkCreate 和 /import
接受的形态相同——因此该载荷可原样回传至 /import。未挂载任何入站的客户端也会包含在内,
其 inboundIds 列表为空。UI 会在 CodeMirror 查看器中展示(复制/下载);程序化调用方
则可在 obj 中获取该数组。
url: >-
#return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
- depth: 2
title: >-
从 JSON 请求体 { "data": "<json>" } 导入客户端,其中 data 是由 /export 生成的
字符串编码数组([{client, inboundIds}])。带有 inboundIds 的项会被创建并挂载到
这些入站;inboundIds 列表为空的项会作为未挂载的客户端记录还原。已存在的 email
绝不会被覆盖——它们会在 skipped 中返回。若任一目标入站处于运行中,则在最后触发一次
Xray 重启。
url: >-
#import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
- depth: 2
title: >-
在一次调用中为多个客户端调整到期时间和/或流量配额。addDays/addBytes 可为负值。对于
到期无限(expiryTime=0)或流量无限(totalGB=0)的客户端,会跳过相应字段——批量延期
绝不会将无限转为有限。可选的 flow 指令会为每个客户端设置 XTLS flow"none" 将其清除,
"xtls-rprx-vision"/"xtls-rprx-vision-udp443" 在入站支持时将其设置(省略或传 "" 则
保持不变)。返回调整数量和按 email 的跳过原因。
url: >-
#shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
- depth: 2
title: >-
在一次调用中启用多个客户端。email 会按入站分组,并对每个入站执行一次读-改-写;运行中
的 Xray(本地或远程节点)会被更新以添加每个用户。请注意,启用一个配额已耗尽或已过期的
客户端只会翻转标志——流量循环会在下一个周期再次将其禁用。返回变更数量和按 email 的
跳过原因。
url: >-
#enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
- depth: 2
title: >-
在一次调用中禁用多个客户端。email 会按入站分组,并对每个入站执行一次读-改-写;运行中
的 Xray(本地或远程节点)会被更新以移除每个用户。返回变更数量和按 email 的跳过原因。
url: >-
#disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
- depth: 2
title: >-
在一次调用中删除多个客户端。服务端会顺序处理该列表,使每次删除都能看到上一次删除已
提交的状态——避免了面板侧按 email 扇出时存在的竞态。传入 keepTraffic=true 可在删除
后保留 xray_client_traffic 记录。
url: >-
#delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
- depth: 2
title: >-
在一次调用中创建多个客户端。请求体是一个 {client, inboundIds} 载荷的 JSON 数组
——与 /add 接受的形态相同。各项按顺序处理;对于失败的项(例如 email 重复)会返回
按 email 的跳过原因。若任一入站处于运行中,则在最后触发一次 Xray 重启。
url: >-
#create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
- depth: 2
title: >-
在一次调用中将多个客户端加入某个分组。会更新 clients.group_name,并在单个事务中修补
每个所属入站的 settings JSON 内匹配的客户端条目。若该分组名尚不存在(无论是在
client_groups 中还是作为派生标签),则会将其自动创建为持久化分组。要清除分组标签,
请改用 /groups/bulkRemove。
url: >-
#add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
- depth: 2
title: >-
在一次调用中清除多个客户端的分组标签。与 /groups/bulkAdd 相反。客户端本身会保留——
仅从 clients.group_name 以及每个所属入站的 settings JSON 中清除分组标签。若某分组的
全部成员都被移除,该分组将变为空。
url: >-
#clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
- depth: 2
title: >-
在一次调用中将多个现有客户端挂载到多个入站。每个客户端都保留其身份
email/UUID/password/subId)以及共享的流量记录;所有客户端会在单次 AddInboundClient
调用中被添加到一个目标入站。已存在于目标上的客户端会在 skipped 中报告。返回按 email 的
attached/skipped/errors 列表,并在任一目标入站处于运行中时触发一次 Xray 重启。
url: >-
#attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
- depth: 2
title: >-
bulkAttach 的镜像操作:在一次调用中将多个现有客户端从多个入站上分离。对于每个 email,
会将该客户端当前的入站集合与请求的集合取交集,并仅从这些入站上分离;客户端当前未挂载的
(email, inbound) 组合会被静默地视为空操作。未挂载到任一请求入站的 email 会在 skipped
中报告。即使客户端记录因此变为孤立,也会被保留——如需完全移除请使用 bulkDel。返回按
email 的 detached/skipped/errors 列表,并在任一目标入站处于运行中时触发一次 Xray
重启。
url: >-
#mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
- depth: 2
title: >-
在一次调用中将多个客户端的上行/下行计数器清零。循环执行单个重置流程,使每个客户端在其
挂载的各入站上被重新启用,并推送到 Xray/远程节点。返回成功重置的客户端数量。
url: >-
#zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
- depth: 2
title: >-
列出所有客户端分组及其成员数量。将持久化分组(client_groups 中的记录,包括空占位符)
与当前在客户端上设置的去重后的 group_name 值合并。按字母顺序排序(不区分大小写)。
url: >-
#list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
- depth: 2
title: >-
仅返回当前属于指定分组的客户端 email 列表。适用于将单个批量操作扇出到整个分组,而无需
往返获取完整的客户端列表。
url: >-
#return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
- depth: 2
title: >-
创建一个新的空(占位)分组。即使尚未向其添加任何客户端,该分组也会在客户端表单和筛选
抽屉中变为可选。若已存在同名分组,则报错。
url: >-
#create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
- depth: 2
title: >-
重命名分组。新名称会应用到 client_groups 记录,并在单个事务中传播到每个匹配的客户端
(包括 clients.group_name 以及每个所属入站的 settings JSON 内的客户端条目)。返回
标签被更新的客户端数量。
url: >-
#rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
- depth: 2
title: >-
移除分组。删除 client_groups 记录,并从每个匹配的客户端清除分组标签(包括
clients.group_name 以及入站 settings JSON)。客户端本身不会被删除——如需删除请先按
分组筛选后再使用 /bulkDel。返回标签被清除的客户端数量。
url: >-
#remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
- depth: 2
title: >-
将单个客户端的上行/下行计数器清零。会在每个挂载的入站上重新启用该客户端,并将变更推送
到 Xray(或远程节点),使流量耗尽的用户能够立即重新连接。
url: >-
#zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
- depth: 2
title: >-
手动调整某个客户端的上传 + 下载计数器。适用于从外部计费系统迁移的场景。
url: >-
#manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
- depth: 2
title: >-
列出曾使用指定客户端凭据连接过的来源 IP。返回一个 "ip (timestamp)" 字符串数组。
url: >-
#list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
- depth: 2
title: 重置某个客户端已记录的 IP 列表。
url: '#reset-the-recorded-ip-list-for-a-client'
- depth: 2
title: >-
列出当前已连接的客户端 email(在心跳窗口内最近一次出现过),并跨所有节点去重。
url: >-
#list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
- depth: 2
title: >-
按实际承载每个客户端的节点的 panelGuid 分组的在线客户端 email。本地面板使用自身的
GUID;链路中(任意深度)的每个节点使用其自身的 GUID。让入站页面能将在线状态归因到
真实节点,而非它所经由的中间节点。
url: >-
#online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
- depth: 2
title: >-
按观测到这些 IP 的节点的 panelGuid 分组的按客户端来源 IP。让中央面板能使用每个节点
所见的真实访客 IP 来归因并执行按客户端的 IP 限制,而非它所经由的中间面板的地址。
url: >-
#per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
- depth: 2
title: >-
在心跳窗口内承载过流量的入站标签,按承载节点的 panelGuid 分组。与 onlinesByGuid 配合,
使入站页面只在多入站客户端实际使用过的入站上将其标记为在线。不报告按入站活动的节点
将被省略。
url: >-
#inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
- depth: 2
title: 客户端 email → 最近一次出现的 unix 时间戳的映射。
url: '#map-of-client-email--last-seen-unix-timestamp'
- depth: 2
title: 按 email 标识的客户端的流量计数器。
url: '#traffic-counters-for-a-client-identified-by-email'
- depth: 2
title: >-
返回与该订阅 ID 匹配的客户端的每个协议 URLvless://、vmess://、trojan://、ss://、
hysteria://、hy2://)。结果集与 /sub/<subId> 相同,但以 JSON 数组形式返回——不含
base64。当某入站设置了 streamSettings.externalProxy 时,每个外部代理会发出一条 URL。
当该 subId 没有已启用的客户端时返回空数组。
url: >-
#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- depth: 2
title: >-
返回单个客户端在所有挂载入站上的每个 URL——与面板 UI 中“复制 URL”按钮所复制的字符串
相同。支持的协议:vmess、vless、trojan、shadowsocks、hysteria。若设置了
streamSettings.externalProxy,则每个外部代理返回一条 URL。没有 URL 形式的协议
socks、http、mixed、wireguard、dokodemo、tunnel)不产生任何内容。
url: >-
#return-every-url-for-one-client-across-all-attached-inbounds--the-same-strings-the-copy-url-button-copies-in-the-panel-ui-supported-protocols-vmess-vless-trojan-shadowsocks-hysteria-if-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
structuredData:
headings:
- content: >-
列出每个客户端及其挂载的入站 ID 和流量记录。reverse 字段若已设置,将以嵌套 JSON
对象的形式返回(写入时仍接受旧版的 JSON 编码字符串形式)。
id: >-
list-every-client-with-its-attached-inbound-ids-and-traffic-record-the-reverse-field-if-set-is-returned-as-a-nested-json-object-legacy-json-encoded-string-form-is-still-accepted-on-write
- content: >-
在服务端对客户端进行筛选、排序和分页。每一项都是精简记录(不含
uuid/password/auth/flow/security/reverse/tgId),因此客户端页面只需几 KB
即可承载约 25 行,而无需返回整张表。响应中还包含一个基于完整数据库行集计算的汇总,
这样在用户分页或筛选时仪表盘计数器仍保持稳定。每页上限为 200;可调用 /get/:email
获取某个客户端用于编辑/信息弹窗的完整载荷。
id: >-
filter-sort-and-paginate-clients-on-the-server-each-item-is-a-slim-row-no-uuidpasswordauthflowsecurityreversetgid-so-the-clients-page-can-ship-25-ish-rows-in-a-few-kb-instead-of-the-full-table-the-response-also-includes-a-summary-computed-across-the-full-db-row-set-so-dashboard-counters-stay-stable-as-the-user-paginates-or-filters-page-size-capped-at-200-fetch-getemail-to-obtain-the-full-per-client-payload-for-an-editinfo-modal
- content: >-
按 email 获取单个客户端,包括它所挂载的入站 ID 和外部配置 ID。
id: >-
fetch-one-client-by-email-including-the-inbound-ids-and-external-config-ids-it-is-attached-to
- content: >-
在一次调用中创建一个新客户端并将其挂载到一个或多个入站。请求体为 JSON。各协议的密钥
VLESS/VMess 的 UUID、Trojan/Shadowsocks 的 password、Hysteria 的 auth)在
省略时由服务端生成,因此调用方只需发送通用字段。
id: >-
create-a-new-client-and-attach-it-to-one-or-more-inbounds-in-a-single-call-body-is-json-per-protocol-secrets-uuid-for-vlessvmess-password-for-trojanshadowsocks-auth-for-hysteria-are-generated-server-side-when-omitted-so-callers-can-send-only-the-universal-fields
- content: >-
按 email 更新现有客户端。变更会传播到每个挂载的入站。请求体为 JSON 客户端载荷——
请提供你希望保留的完整字段集(服务端会替换整条记录,而非局部更新)。
id: >-
update-an-existing-client-by-email-changes-propagate-to-every-attached-inbound-body-is-the-json-client-payload--supply-the-full-set-of-fields-you-want-to-keep-the-server-replaces-the-row-it-does-not-patch
- content: >-
按 email 删除客户端。将其从每个挂载的入站中移除,并删除其流量记录,除非传入
keepTraffic=1。
id: >-
delete-a-client-by-email-removes-it-from-every-attached-inbound-and-drops-its-traffic-record-unless-keeptraffic1-is-passed
- content: >-
将现有客户端挂载到一个或多个额外的入站。请求体为 JSON。
id: >-
attach-an-existing-client-to-one-or-more-additional-inbounds-body-is-json
- content: 在不删除客户端的前提下,将其从一个或多个入站上分离。
id: detach-a-client-from-one-or-more-inbounds-without-deleting-the-client
- content: >-
替换某客户端的外部链接(在其订阅中呈现的按客户端分享链接和远程订阅 URL)。发送完整
集合;服务端会替换所有记录。
id: >-
replace-a-clients-external-links-per-client-share-links-and-remote-subscription-urls-surfaced-in-their-subscription-sends-the-full-set-the-server-replaces-all-rows
- content: >-
全局重置每个客户端的上行/下行计数器。配额和到期时间不受影响。若有任何计数器实际发生
变动,则触发一次 Xray 重启。
id: >-
reset-the-updown-counters-for-every-client-globally-quotas-and-expiry-are-not-affected-triggers-an-xray-restart-if-any-counter-actually-moved
- content: >-
删除所有流量配额已耗尽(在禁用重置时,used >= total)或已过期的客户端。返回删除
数量,并在任一客户端位于运行中的入站时触发一次 Xray 重启。
id: >-
delete-every-client-whose-traffic-quota-is-exhausted-used--total-when-reset-is-disabled-or-whose-expiry-has-passed-returns-the-deleted-count-and-triggers-an-xray-restart-when-any-client-was-on-a-running-inbound
- content: >-
删除所有未挂载到任何入站的客户端,连同其流量记录、IP 日志和外部链接一并删除。适用于
清理在其入站被移除后处于未挂载状态的客户端。返回删除数量。无法撤销。
id: >-
delete-every-client-that-is-not-attached-to-any-inbound-along-with-its-traffic-record-ip-log-and-external-links-useful-for-clearing-clients-left-unattached-after-their-inbounds-were-removed-returns-the-deleted-count-cannot-be-undone
- content: >-
以 {client, inboundIds} 数组的形式返回每个客户端——与 /bulkCreate 和 /import
接受的形态相同——因此该载荷可原样回传至 /import。未挂载任何入站的客户端也会包含在内,
其 inboundIds 列表为空。UI 会在 CodeMirror 查看器中展示(复制/下载);程序化调用方
则可在 obj 中获取该数组。
id: >-
return-every-client-as-a-client-inboundids-array--the-same-shape-bulkcreate-and-import-accept--so-the-payload-round-trips-straight-back-through-import-clients-with-no-inbound-attachment-are-included-with-an-empty-inboundids-list-the-ui-shows-this-in-a-codemirror-viewer-copy--download-programmatic-callers-get-the-array-in-obj
- content: >-
从 JSON 请求体 { "data": "<json>" } 导入客户端,其中 data 是由 /export 生成的
字符串编码数组([{client, inboundIds}])。带有 inboundIds 的项会被创建并挂载到
这些入站;inboundIds 列表为空的项会作为未挂载的客户端记录还原。已存在的 email
绝不会被覆盖——它们会在 skipped 中返回。若任一目标入站处于运行中,则在最后触发一次
Xray 重启。
id: >-
import-clients-from-a-json-body--data-json--where-data-is-a-string-encoded-array-produced-by-export-client-inboundids-items-with-inboundids-are-created-and-attached-to-those-inbounds-items-with-an-empty-inboundids-list-are-restored-as-unattached-client-records-existing-emails-are-never-overwritten--they-are-returned-in-skipped-triggers-a-single-xray-restart-at-the-end-if-any-target-inbound-was-running
- content: >-
在一次调用中为多个客户端调整到期时间和/或流量配额。addDays/addBytes 可为负值。对于
到期无限(expiryTime=0)或流量无限(totalGB=0)的客户端,会跳过相应字段——批量延期
绝不会将无限转为有限。可选的 flow 指令会为每个客户端设置 XTLS flow"none" 将其清除,
"xtls-rprx-vision"/"xtls-rprx-vision-udp443" 在入站支持时将其设置(省略或传 "" 则
保持不变)。返回调整数量和按 email 的跳过原因。
id: >-
shift-expiry-andor-traffic-quota-for-many-clients-in-one-call-adddaysaddbytes-may-be-negative-clients-with-unlimited-expiry-expirytime0-or-unlimited-traffic-totalgb0-are-skipped-for-the-corresponding-field--bulk-extend-never-converts-unlimited-to-limited-the-optional-flow-directive-sets-the-xtls-flow-on-every-client-none-clears-it-xtls-rprx-visionxtls-rprx-vision-udp443-set-it-where-the-inbound-supports-it-omit-or--to-leave-it-unchanged-returns-the-adjusted-count-and-per-email-skip-reasons
- content: >-
在一次调用中启用多个客户端。email 会按入站分组,并对每个入站执行一次读-改-写;运行中
的 Xray(本地或远程节点)会被更新以添加每个用户。请注意,启用一个配额已耗尽或已过期的
客户端只会翻转标志——流量循环会在下一个周期再次将其禁用。返回变更数量和按 email 的
跳过原因。
id: >-
enable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-add-each-user-note-that-enabling-a-client-whose-quota-is-exhausted-or-whose-expiry-has-passed-only-flips-the-flag--the-traffic-loop-will-disable-it-again-on-the-next-tick-returns-the-changed-count-and-per-email-skip-reasons
- content: >-
在一次调用中禁用多个客户端。email 会按入站分组,并对每个入站执行一次读-改-写;运行中
的 Xray(本地或远程节点)会被更新以移除每个用户。返回变更数量和按 email 的跳过原因。
id: >-
disable-many-clients-in-one-call-emails-are-grouped-by-inbound-and-applied-with-a-single-read-modify-write-per-inbound-the-running-xray-local-or-remote-node-is-updated-to-remove-each-user-returns-the-changed-count-and-per-email-skip-reasons
- content: >-
在一次调用中删除多个客户端。服务端会顺序处理该列表,使每次删除都能看到上一次删除已
提交的状态——避免了面板侧按 email 扇出时存在的竞态。传入 keepTraffic=true 可在删除
后保留 xray_client_traffic 记录。
id: >-
delete-many-clients-in-one-call-the-server-processes-the-list-sequentially-so-each-delete-sees-the-committed-state-of-the-previous-one--avoids-the-race-the-per-email-fan-out-had-on-the-panel-side-pass-keeptraffictrue-to-retain-the-xray_client_traffic-rows-after-deletion
- content: >-
在一次调用中创建多个客户端。请求体是一个 {client, inboundIds} 载荷的 JSON 数组
——与 /add 接受的形态相同。各项按顺序处理;对于失败的项(例如 email 重复)会返回
按 email 的跳过原因。若任一入站处于运行中,则在最后触发一次 Xray 重启。
id: >-
create-many-clients-in-one-call-body-is-a-json-array-of-client-inboundids-payloads--the-same-shape-add-accepts-items-are-processed-sequentially-per-email-skip-reasons-are-returned-for-items-that-fail-eg-duplicate-email-triggers-a-single-xray-restart-at-the-end-if-any-inbound-was-running
- content: >-
在一次调用中将多个客户端加入某个分组。会更新 clients.group_name,并在单个事务中修补
每个所属入站的 settings JSON 内匹配的客户端条目。若该分组名尚不存在(无论是在
client_groups 中还是作为派生标签),则会将其自动创建为持久化分组。要清除分组标签,
请改用 /groups/bulkRemove。
id: >-
add-many-clients-to-a-group-in-one-call-updates-clientsgroup_name-and-patches-the-matching-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-if-the-group-name-does-not-yet-exist-in-client_groups-or-as-a-derived-label-it-is-auto-created-as-a-persistent-group-to-clear-the-group-label-use-groupsbulkremove-instead
- content: >-
在一次调用中清除多个客户端的分组标签。与 /groups/bulkAdd 相反。客户端本身会保留——
仅从 clients.group_name 以及每个所属入站的 settings JSON 中清除分组标签。若某分组的
全部成员都被移除,该分组将变为空。
id: >-
clear-the-group-label-on-many-clients-in-one-call-inverse-of-groupsbulkadd-clients-themselves-are-kept--only-the-group-label-is-cleared-from-clientsgroup_name-and-from-each-owning-inbounds-settings-json-groups-become-empty-if-all-their-members-are-removed
- content: >-
在一次调用中将多个现有客户端挂载到多个入站。每个客户端都保留其身份
email/UUID/password/subId)以及共享的流量记录;所有客户端会在单次 AddInboundClient
调用中被添加到一个目标入站。已存在于目标上的客户端会在 skipped 中报告。返回按 email 的
attached/skipped/errors 列表,并在任一目标入站处于运行中时触发一次 Xray 重启。
id: >-
attach-many-existing-clients-to-many-inbounds-in-one-call-each-client-keeps-its-identity-emailuuidpasswordsubid-and-a-shared-traffic-row-all-clients-are-added-to-a-target-inbound-in-a-single-addinboundclient-call-clients-already-present-on-a-target-are-reported-under-skipped-returns-per-email-attachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
- content: >-
bulkAttach 的镜像操作:在一次调用中将多个现有客户端从多个入站上分离。对于每个 email,
会将该客户端当前的入站集合与请求的集合取交集,并仅从这些入站上分离;客户端当前未挂载的
(email, inbound) 组合会被静默地视为空操作。未挂载到任一请求入站的 email 会在 skipped
中报告。即使客户端记录因此变为孤立,也会被保留——如需完全移除请使用 bulkDel。返回按
email 的 detached/skipped/errors 列表,并在任一目标入站处于运行中时触发一次 Xray
重启。
id: >-
mirror-of-bulkattach-detach-many-existing-clients-from-many-inbounds-in-one-call-for-each-email-intersects-the-clients-current-inbounds-with-the-requested-set-and-detaches-from-those-only-email-inbound-pairs-where-the-client-is-not-currently-attached-are-silently-no-ops-emails-not-attached-to-any-of-the-requested-inbounds-are-reported-under-skipped-client-records-are-kept-even-if-they-become-orphaned--use-bulkdel-for-full-removal-returns-per-email-detachedskippederrors-lists-and-triggers-a-single-xray-restart-if-any-target-inbound-was-running
- content: >-
在一次调用中将多个客户端的上行/下行计数器清零。循环执行单个重置流程,使每个客户端在其
挂载的各入站上被重新启用,并推送到 Xray/远程节点。返回成功重置的客户端数量。
id: >-
zero-updown-counters-for-many-clients-in-one-call-loops-the-single-reset-path-so-each-client-is-re-enabled-across-its-attached-inbounds-and-pushed-to-xrayremote-nodes-returns-the-count-of-successfully-reset-clients
- content: >-
列出所有客户端分组及其成员数量。将持久化分组(client_groups 中的记录,包括空占位符)
与当前在客户端上设置的去重后的 group_name 值合并。按字母顺序排序(不区分大小写)。
id: >-
list-all-client-groups-with-their-member-counts-merges-persisted-groups-rows-in-client_groups-including-empty-placeholders-with-the-distinct-group_name-values-currently-set-on-clients-sorted-alphabetically-case-insensitive
- content: >-
仅返回当前属于指定分组的客户端 email 列表。适用于将单个批量操作扇出到整个分组,而无需
往返获取完整的客户端列表。
id: >-
return-just-the-email-list-of-clients-that-currently-belong-to-the-given-group-useful-for-fanning-a-single-bulk-action-over-an-entire-group-without-round-tripping-the-full-client-list
- content: >-
创建一个新的空(占位)分组。即使尚未向其添加任何客户端,该分组也会在客户端表单和筛选
抽屉中变为可选。若已存在同名分组,则报错。
id: >-
create-a-new-empty-placeholder-group-the-group-becomes-selectable-in-client-forms-and-the-filter-drawer-even-before-any-client-is-added-to-it-errors-if-a-group-with-the-same-name-already-exists
- content: >-
重命名分组。新名称会应用到 client_groups 记录,并在单个事务中传播到每个匹配的客户端
(包括 clients.group_name 以及每个所属入站的 settings JSON 内的客户端条目)。返回
标签被更新的客户端数量。
id: >-
rename-a-group-the-new-name-is-applied-to-the-client_groups-row-and-propagated-to-every-matching-client-both-clientsgroup_name-and-the-client-entry-inside-every-owning-inbounds-settings-json-in-a-single-transaction-returns-the-number-of-clients-whose-label-was-updated
- content: >-
移除分组。删除 client_groups 记录,并从每个匹配的客户端清除分组标签(包括
clients.group_name 以及入站 settings JSON)。客户端本身不会被删除——如需删除请先按
分组筛选后再使用 /bulkDel。返回标签被清除的客户端数量。
id: >-
remove-a-group-deletes-the-client_groups-row-and-clears-the-group-label-from-every-matching-client-both-clientsgroup_name-and-the-inbound-settings-json-the-clients-themselves-are-not-deleted--use-bulkdel-after-filtering-by-group-for-that-returns-the-count-of-clients-whose-label-was-cleared
- content: >-
将单个客户端的上行/下行计数器清零。会在每个挂载的入站上重新启用该客户端,并将变更推送
到 Xray(或远程节点),使流量耗尽的用户能够立即重新连接。
id: >-
zero-out-a-single-clients-updown-counters-re-enables-the-client-across-every-attached-inbound-and-pushes-the-change-to-xray-or-the-remote-node-so-depleted-users-can-connect-again-immediately
- content: >-
手动调整某个客户端的上传 + 下载计数器。适用于从外部计费系统迁移的场景。
id: >-
manually-adjust-a-clients-upload--download-counters-useful-for-migrations-from-external-accounting-systems
- content: >-
列出曾使用指定客户端凭据连接过的来源 IP。返回一个 "ip (timestamp)" 字符串数组。
id: >-
list-source-ips-that-have-connected-with-the-given-clients-credentials-returns-an-array-of-ip-timestamp-strings
- content: 重置某个客户端已记录的 IP 列表。
id: reset-the-recorded-ip-list-for-a-client
- content: >-
列出当前已连接的客户端 email(在心跳窗口内最近一次出现过),并跨所有节点去重。
id: >-
list-the-emails-of-currently-connected-clients-last-seen-within-the-heartbeat-window-deduped-across-every-node
- content: >-
按实际承载每个客户端的节点的 panelGuid 分组的在线客户端 email。本地面板使用自身的
GUID;链路中(任意深度)的每个节点使用其自身的 GUID。让入站页面能将在线状态归因到
真实节点,而非它所经由的中间节点。
id: >-
online-client-emails-grouped-by-the-panelguid-of-the-node-that-physically-hosts-each-client-the-local-panel-uses-its-own-guid-each-node-at-any-depth-in-a-chain-uses-its-guid-lets-the-inbounds-page-attribute-online-status-to-the-real-node-instead-of-the-intermediate-one-it-syncs-through
- content: >-
按观测到这些 IP 的节点的 panelGuid 分组的按客户端来源 IP。让中央面板能使用每个节点
所见的真实访客 IP 来归因并执行按客户端的 IP 限制,而非它所经由的中间面板的地址。
id: >-
per-client-source-ips-grouped-by-the-panelguid-of-the-node-that-observed-them-lets-the-central-panel-attribute-and-enforce-per-client-ip-limits-using-the-real-visitor-ips-each-node-sees-instead-of-the-address-of-the-intermediate-panel-it-syncs-through
- content: >-
在心跳窗口内承载过流量的入站标签,按承载节点的 panelGuid 分组。与 onlinesByGuid 配合,
使入站页面只在多入站客户端实际使用过的入站上将其标记为在线。不报告按入站活动的节点
将被省略。
id: >-
inbound-tags-that-carried-traffic-within-the-heartbeat-window-grouped-by-the-hosting-nodes-panelguid-pairs-with-onlinesbyguid-so-the-inbounds-page-only-marks-a-multi-inbound-client-online-on-the-inbounds-it-actually-used-nodes-that-do-not-report-per-inbound-activity-are-absent
- content: 客户端 email → 最近一次出现的 unix 时间戳的映射。
id: map-of-client-email--last-seen-unix-timestamp
- content: 按 email 标识的客户端的流量计数器。
id: traffic-counters-for-a-client-identified-by-email
- content: >-
返回与该订阅 ID 匹配的客户端的每个协议 URLvless://、vmess://、trojan://、ss://、
hysteria://、hy2://)。结果集与 /sub/<subId> 相同,但以 JSON 数组形式返回——不含
base64。当某入站设置了 streamSettings.externalProxy 时,每个外部代理会发出一条 URL。
当该 subId 没有已启用的客户端时返回空数组。
id: >-
return-every-protocol-url-vless-vmess-trojan-ss-hysteria-hy2-for-clients-matching-the-subscription-id-same-result-set-as-subsubid-but-as-a-json-array--no-base64-when-an-inbound-has-streamsettingsexternalproxy-set-one-url-is-emitted-per-external-proxy-empty-array-when-the-subid-has-no-enabled-clients
- content: >-
返回单个客户端在所有挂载入站上的每个 URL——与面板 UI 中“复制 URL”按钮所复制的字符串
相同。支持的协议:vmess、vless、trojan、shadowsocks、hysteria。若设置了
streamSettings.externalProxy,则每个外部代理返回一条 URL。没有 URL 形式的协议
socks、http、mixed、wireguard、dokodemo、tunnel)不产生任何内容。
id: >-
return-every-url-for-one-client-across-all-attached-inbounds--the-same-strings-the-copy-url-button-copies-in-the-panel-ui-supported-protocols-vmess-vless-trojan-shadowsocks-hysteria-if-streamsettingsexternalproxy-is-set-returns-one-url-per-external-proxy-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/clients/list","method":"get"},{"path":"/panel/api/clients/list/paged","method":"get"},{"path":"/panel/api/clients/get/{email}","method":"get"},{"path":"/panel/api/clients/add","method":"post"},{"path":"/panel/api/clients/update/{email}","method":"post"},{"path":"/panel/api/clients/del/{email}","method":"post"},{"path":"/panel/api/clients/{email}/attach","method":"post"},{"path":"/panel/api/clients/{email}/detach","method":"post"},{"path":"/panel/api/clients/{email}/externalLinks","method":"post"},{"path":"/panel/api/clients/resetAllTraffics","method":"post"},{"path":"/panel/api/clients/delDepleted","method":"post"},{"path":"/panel/api/clients/delOrphans","method":"post"},{"path":"/panel/api/clients/export","method":"get"},{"path":"/panel/api/clients/import","method":"post"},{"path":"/panel/api/clients/bulkAdjust","method":"post"},{"path":"/panel/api/clients/bulkEnable","method":"post"},{"path":"/panel/api/clients/bulkDisable","method":"post"},{"path":"/panel/api/clients/bulkDel","method":"post"},{"path":"/panel/api/clients/bulkCreate","method":"post"},{"path":"/panel/api/clients/groups/bulkAdd","method":"post"},{"path":"/panel/api/clients/groups/bulkRemove","method":"post"},{"path":"/panel/api/clients/bulkAttach","method":"post"},{"path":"/panel/api/clients/bulkDetach","method":"post"},{"path":"/panel/api/clients/bulkResetTraffic","method":"post"},{"path":"/panel/api/clients/groups","method":"get"},{"path":"/panel/api/clients/groups/{name}/emails","method":"get"},{"path":"/panel/api/clients/groups/create","method":"post"},{"path":"/panel/api/clients/groups/rename","method":"post"},{"path":"/panel/api/clients/groups/delete","method":"post"},{"path":"/panel/api/clients/resetTraffic/{email}","method":"post"},{"path":"/panel/api/clients/updateTraffic/{email}","method":"post"},{"path":"/panel/api/clients/ips/{email}","method":"post"},{"path":"/panel/api/clients/clearIps/{email}","method":"post"},{"path":"/panel/api/clients/onlines","method":"post"},{"path":"/panel/api/clients/onlinesByGuid","method":"post"},{"path":"/panel/api/clients/clientIpsByGuid","method":"post"},{"path":"/panel/api/clients/activeInbounds","method":"post"},{"path":"/panel/api/clients/lastOnline","method":"post"},{"path":"/panel/api/clients/traffic/{email}","method":"get"},{"path":"/panel/api/clients/subLinks/{subId}","method":"get"},{"path":"/panel/api/clients/links/{email}","method":"get"}]} showTitle />
</>
);
}
@@ -0,0 +1,108 @@
---
title: 主机
description: >-
按入站逐项覆盖的端点。每个启用的主机都会额外生成一条订阅链接/代理,可拥有独立的
地址/端口/TLS,从而取代已弃用的 externalProxy 数组。所有端点均位于 /panel/api/hosts
之下。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
List every host across all inbounds, grouped by inbound then ordered by
sort order.
url: >-
#list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
- depth: 2
title: Fetch a single host by ID.
url: '#fetch-a-single-host-by-id'
- depth: 2
title: Fetch one inbound's hosts, ordered by sort order then id.
url: '#fetch-one-inbounds-hosts-ordered-by-sort-order-then-id'
- depth: 2
title: Distinct, sorted set of tags used across all hosts.
url: '#distinct-sorted-set-of-tags-used-across-all-hosts'
- depth: 2
title: >-
Create a host on an inbound. inboundId and remark are required; security
defaults to "same" (inherit the inbound).
url: >-
#create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
- depth: 2
title: >-
Replace a hosts content. The inbound and sort order are immutable here
(use /reorder for ordering).
url: >-
#replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
- depth: 2
title: Delete a host.
url: '#delete-a-host'
- depth: 2
title: >-
Enable or disable a single host (disabled hosts are skipped in
subscriptions).
url: >-
#enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
- depth: 2
title: Set host sort order by the position of each id in the array.
url: '#set-host-sort-order-by-the-position-of-each-id-in-the-array'
- depth: 2
title: Enable or disable many hosts in one call.
url: '#enable-or-disable-many-hosts-in-one-call'
- depth: 2
title: Delete many hosts in one call.
url: '#delete-many-hosts-in-one-call'
structuredData:
headings:
- content: >-
List every host across all inbounds, grouped by inbound then ordered
by sort order.
id: >-
list-every-host-across-all-inbounds-grouped-by-inbound-then-ordered-by-sort-order
- content: Fetch a single host by ID.
id: fetch-a-single-host-by-id
- content: Fetch one inbound's hosts, ordered by sort order then id.
id: fetch-one-inbounds-hosts-ordered-by-sort-order-then-id
- content: Distinct, sorted set of tags used across all hosts.
id: distinct-sorted-set-of-tags-used-across-all-hosts
- content: >-
Create a host on an inbound. inboundId and remark are required;
security defaults to "same" (inherit the inbound).
id: >-
create-a-host-on-an-inbound-inboundid-and-remark-are-required-security-defaults-to-same-inherit-the-inbound
- content: >-
Replace a hosts content. The inbound and sort order are immutable
here (use /reorder for ordering).
id: >-
replace-a-hosts-content-the-inbound-and-sort-order-are-immutable-here-use-reorder-for-ordering
- content: Delete a host.
id: delete-a-host
- content: >-
Enable or disable a single host (disabled hosts are skipped in
subscriptions).
id: >-
enable-or-disable-a-single-host-disabled-hosts-are-skipped-in-subscriptions
- content: Set host sort order by the position of each id in the array.
id: set-host-sort-order-by-the-position-of-each-id-in-the-array
- content: Enable or disable many hosts in one call.
id: enable-or-disable-many-hosts-in-one-call
- content: Delete many hosts in one call.
id: delete-many-hosts-in-one-call
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/hosts/list","method":"get"},{"path":"/panel/api/hosts/get/{id}","method":"get"},{"path":"/panel/api/hosts/byInbound/{inboundId}","method":"get"},{"path":"/panel/api/hosts/tags","method":"get"},{"path":"/panel/api/hosts/add","method":"post"},{"path":"/panel/api/hosts/update/{id}","method":"post"},{"path":"/panel/api/hosts/del/{id}","method":"post"},{"path":"/panel/api/hosts/setEnable/{id}","method":"post"},{"path":"/panel/api/hosts/reorder","method":"post"},{"path":"/panel/api/hosts/bulk/setEnable","method":"post"},{"path":"/panel/api/hosts/bulk/del","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,186 @@
---
title: 入站
description: >-
管理入站配置及其客户端。所有端点均位于 /panel/api/inbounds 下,需要已登录的会话或 Bearer
令牌。生成链接的端点仅在请求来自已配置的受信任代理时,才会采信转发请求头。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
列出已认证用户拥有的每个入站,包括每个入站的 clientStats 流量计数器。settings、streamSettings 和
sniffing 以嵌套的 JSON 对象形式返回(不含转义字符串);写入时仍接受以 JSON 编码字符串形式回传这些字段的旧版调用方。
url: >-
#list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
- depth: 2
title: >-
与 /list 结构相同,但 settings.clients[] 精简为 {email, enable, comment},且 ClientStats
不附带 UUID/SubId。请将其用于列表页面;当你需要完整的单客户端数据(uuid、password、flow……)时,请调用
/get/:id。
url: >-
#same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
- depth: 2
title: >-
已认证用户入站的轻量级选择器投影。返回 id、remark、tag、protocol、port、由服务端计算的 tlsFlowCapable
标志(当 VLESS 在 TCP 上使用 tls 或 reality,或在 XHTTP 上启用 VLESS encryption / vlessenc
时为 true),以及 ssMethodShadowsocks 加密方式,非 Shadowsocks 入站为空——客户端 UI 用它生成有效的
Shadowsocks 2022 PSK)。请将其用于下拉菜单和附加选择器——它会跳过 settings、streamSettings 和
clientStats,因此即便在拥有数千客户端的面板上,数据负载也能保持精简。
url: >-
#lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
- depth: 2
title: 按数字 ID 获取单个入站。
url: '#fetch-a-single-inbound-by-numeric-id'
- depth: 2
title: >-
创建一个新入站。发送完整的入站数据(protocol、port、settings、streamSettings、sniffing、remark、expiryTime、total、enable)。settings、streamSettings
和 sniffing 可以嵌套 JSON 对象形式发送(推荐),也可以 JSON 编码字符串形式发送(旧版)。
url: >-
#create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
- depth: 2
title: 按 ID 删除一个入站。同时会移除其关联的客户端统计记录行。
url: '#delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows'
- depth: 2
title: >-
在一次调用中删除多个入站。按顺序逐个处理列表;失败会按 id 逐一报告,其余的仍会继续执行。最多重启 xray 一次。
url: >-
#delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
- depth: 2
title: >-
替换一个入站的配置。请求体结构与 /add 相同。对于拥有数千客户端的入站开销较大——若仅切换 enable,请优先使用 /setEnable。
url: >-
#replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
- depth: 2
title: >-
仅切换 enable 标志,而无需序列化整个 settings JSON。推荐用于大型入站上的 UI 开关。
url: >-
#toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
- depth: 2
title: >-
将单个入站的上传 + 下载计数器清零。不会影响单客户端的计数器。
url: >-
#zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
- depth: 2
title: >-
移除某个入站上附加的所有客户端,同时保留入站本身。它会从 settings.clients[] 收集 email,并将其送入优化过的批量删除流程(运行时用户移除
+ 流量记录行清理 + SyncInbound)。此操作具有破坏性且无法撤销。
url: >-
#remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
- depth: 2
title: >-
重置每个入站的上传 + 下载计数器。此操作具有破坏性——统计历史将丢失。
url: >-
#reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
- depth: 2
title: >-
从一段 JSON 数据(例如通过 UI 导出的数据)批量导入一个入站。请求体使用表单编码,仅含一个 "data" 字段。
url: >-
#bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
- depth: 2
title: >-
接收主面板聚合后的单客户端用量,以主面板的 GUID 为键。存储在一个仅用于 UI 显示叠加层和本地配额执行的辅助表中——绝不会并入主面板轮询的本地计数器,因此增量统计保持完整。由节点流量同步任务在面板间调用。
url: >-
#receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
- depth: 2
title: >-
列出附加在主 VLESS/Trojan TCP-TLS 入站上的回落(fallback)规则。每条规则将一个子入站(dest)关联到可选的
SNI/ALPN/path/dest/xver 匹配条件。当 dest 为空时,使用子入站的 listen+port。
url: >-
#list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
- depth: 2
title: >-
替换主入站的整个回落(fallback)列表。请求体为 JSON。会触发 Xray 重启。
url: >-
#replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
structuredData:
headings:
- content: >-
列出已认证用户拥有的每个入站,包括每个入站的 clientStats 流量计数器。settings、streamSettings 和
sniffing 以嵌套的 JSON 对象形式返回(不含转义字符串);写入时仍接受以 JSON 编码字符串形式回传这些字段的旧版调用方。
id: >-
list-every-inbound-owned-by-the-authenticated-user-including-each-inbounds-clientstats-traffic-counters-settings-streamsettings-and-sniffing-are-returned-as-nested-json-objects-no-escaped-strings-legacy-callers-that-send-them-back-as-json-encoded-strings-are-still-accepted-on-write
- content: >-
与 /list 结构相同,但 settings.clients[] 精简为 {email, enable, comment},且
ClientStats 不附带 UUID/SubId。请将其用于列表页面;当你需要完整的单客户端数据(uuid、password、flow……)时,请调用
/get/:id。
id: >-
same-shape-as-list-but-with-settingsclients-stripped-down-to-email-enable-comment-and-clientstats-not-enriched-with-uuidsubid-use-this-for-list-pages-fetch-getid-when-you-need-the-full-per-client-payload-uuid-password-flow-
- content: >-
已认证用户入站的轻量级选择器投影。返回 id、remark、tag、protocol、port、由服务端计算的
tlsFlowCapable 标志(当 VLESS 在 TCP 上使用 tls 或 reality,或在 XHTTP 上启用 VLESS
encryption / vlessenc 时为 true),以及 ssMethodShadowsocks 加密方式,非 Shadowsocks
入站为空——客户端 UI 用它生成有效的 Shadowsocks 2022 PSK)。请将其用于下拉菜单和附加选择器——它会跳过
settings、streamSettings 和 clientStats,因此即便在拥有数千客户端的面板上,数据负载也能保持精简。
id: >-
lightweight-picker-projection-of-the-authenticated-users-inbounds-returns-id-remark-tag-protocol-port-a-server-computed-tlsflowcapable-flag-true-for-vless-on-tcp-with-tls-or-reality-or-on-xhttp-with-vless-encryption--vlessenc-enabled-and-ssmethod-the-shadowsocks-cipher-empty-for-non-shadowsocks-inbounds--used-by-the-client-ui-to-generate-a-valid-shadowsocks-2022-psk-use-this-for-dropdowns-and-attach-pickers--it-skips-settings-streamsettings-and-clientstats-so-the-payload-stays-small-even-on-panels-with-thousands-of-clients
- content: 按数字 ID 获取单个入站。
id: fetch-a-single-inbound-by-numeric-id
- content: >-
创建一个新入站。发送完整的入站数据(protocol、port、settings、streamSettings、sniffing、remark、expiryTime、total、enable)。settings、streamSettings
和 sniffing 可以嵌套 JSON 对象形式发送(推荐),也可以 JSON 编码字符串形式发送(旧版)。
id: >-
create-a-new-inbound-send-the-full-inbound-payload-protocol-port-settings-streamsettings-sniffing-remark-expirytime-total-enable-settings-streamsettings-and-sniffing-may-be-sent-as-nested-json-objects-preferred-or-as-json-encoded-strings-legacy
- content: >-
按 ID 删除一个入站。同时会移除其关联的客户端统计记录行。
id: delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows
- content: >-
在一次调用中删除多个入站。按顺序逐个处理列表;失败会按 id 逐一报告,其余的仍会继续执行。最多重启 xray 一次。
id: >-
delete-many-inbounds-in-one-call-processes-the-list-sequentially-failures-are-reported-per-id-and-the-rest-still-proceed-restarts-xray-at-most-once
- content: >-
替换一个入站的配置。请求体结构与 /add 相同。对于拥有数千客户端的入站开销较大——若仅切换 enable,请优先使用
/setEnable。
id: >-
replace-an-inbounds-configuration-body-shape-mirrors-add-heavy-on-inbounds-with-thousands-of-clients--prefer-setenable-for-enable-only-flips
- content: >-
仅切换 enable 标志,而无需序列化整个 settings JSON。推荐用于大型入站上的 UI 开关。
id: >-
toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
- content: >-
将单个入站的上传 + 下载计数器清零。不会影响单客户端的计数器。
id: >-
zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
- content: >-
移除某个入站上附加的所有客户端,同时保留入站本身。它会从 settings.clients[] 收集 email,并将其送入优化过的批量删除流程(运行时用户移除
+ 流量记录行清理 + SyncInbound)。此操作具有破坏性且无法撤销。
id: >-
remove-every-client-attached-to-a-single-inbound-while-keeping-the-inbound-itself-collects-emails-from-settingsclients-and-feeds-them-into-the-optimized-bulk-delete-path-runtime-user-removal--traffic-row-cleanup--syncinbound-destructive-and-cannot-be-undone
- content: >-
重置每个入站的上传 + 下载计数器。此操作具有破坏性——统计历史将丢失。
id: >-
reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
- content: >-
从一段 JSON 数据(例如通过 UI 导出的数据)批量导入一个入站。请求体使用表单编码,仅含一个 "data" 字段。
id: >-
bulk-import-an-inbound-from-a-json-blob-eg-one-exported-via-the-ui-the-body-uses-form-encoding-with-a-single-data-field
- content: >-
接收主面板聚合后的单客户端用量,以主面板的 GUID 为键。存储在一个仅用于 UI 显示叠加层和本地配额执行的辅助表中——绝不会并入主面板轮询的本地计数器,因此增量统计保持完整。由节点流量同步任务在面板间调用。
id: >-
receive-a-master-panels-aggregated-per-client-usage-keyed-by-the-masters-guid-stored-in-a-side-table-used-only-for-the-ui-display-overlay-and-local-quota-enforcement--never-folded-into-the-local-counters-that-masters-poll-so-delta-accounting-stays-intact-called-panel-to-panel-by-the-node-traffic-sync-job
- content: >-
列出附加在主 VLESS/Trojan TCP-TLS 入站上的回落(fallback)规则。每条规则将一个子入站(dest)关联到可选的
SNI/ALPN/path/dest/xver 匹配条件。当 dest 为空时,使用子入站的 listen+port。
id: >-
list-the-fallback-rules-attached-to-a-master-vlesstrojan-tcp-tls-inbound-each-rule-links-one-child-inbound-the-dest-to-optional-snialpnpathdestxver-match-criteria-when-dest-is-empty-the-child-inbounds-listenport-is-used
- content: >-
替换主入站的整个回落(fallback)列表。请求体为 JSON。会触发 Xray 重启。
id: >-
replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/inbounds/list","method":"get"},{"path":"/panel/api/inbounds/list/slim","method":"get"},{"path":"/panel/api/inbounds/options","method":"get"},{"path":"/panel/api/inbounds/get/{id}","method":"get"},{"path":"/panel/api/inbounds/add","method":"post"},{"path":"/panel/api/inbounds/del/{id}","method":"post"},{"path":"/panel/api/inbounds/bulkDel","method":"post"},{"path":"/panel/api/inbounds/update/{id}","method":"post"},{"path":"/panel/api/inbounds/setEnable/{id}","method":"post"},{"path":"/panel/api/inbounds/{id}/resetTraffic","method":"post"},{"path":"/panel/api/inbounds/{id}/delAllClients","method":"post"},{"path":"/panel/api/inbounds/resetAllTraffics","method":"post"},{"path":"/panel/api/inbounds/import","method":"post"},{"path":"/panel/api/inbounds/pushClientTraffics","method":"post"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"get"},{"path":"/panel/api/inbounds/{id}/fallbacks","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,37 @@
---
title: API 参考
description: 3x-ui 面板的 REST API —— 涵盖认证、入站、客户端、服务器状态等,依据 OpenAPI 规范自动生成。
icon: Webhook
---
3x-ui 面板提供了一套用于自动化的 REST API。以下页面根据面板的 OpenAPI 规范自动生成,因此始终与所记录的 schema 保持一致。
## 认证
请求可使用 **会话 Cookie**(来自 `POST /login`)或 **Bearer token** 进行认证:
```text
Authorization: Bearer <token>
```
在面板中创建 API token;它们拥有完整的管理员权限,因此请妥善保管。参见 [API Tokens](/docs/reference/api/api-tokens)。
为下方任意端点构建一个已认证的请求:
<ApiRequestBuilder />
## 按领域浏览
<Cards>
<Card title="认证" href="/docs/reference/api/authentication" />
<Card title="入站" href="/docs/reference/api/inbounds" />
<Card title="客户端" href="/docs/reference/api/clients" />
<Card title="服务器" href="/docs/reference/api/server" />
<Card title="设置" href="/docs/reference/api/settings" />
<Card title="Xray 设置" href="/docs/reference/api/xray-settings" />
</Cards>
<Callout type="info">
本参考文档由 `public/openapi.json` 通过 `pnpm gen:api` 重新生成。
请勿手动编辑自动生成的标签页面。
</Callout>
@@ -0,0 +1,19 @@
{
"title": "API 参考",
"icon": "Webhook",
"pages": [
"index",
"authentication",
"api-tokens",
"inbounds",
"clients",
"server",
"settings",
"xray-settings",
"subscription-server",
"hosts",
"nodes",
"backup",
"websocket"
]
}
@@ -0,0 +1,182 @@
---
title: 节点
description: >-
管理作为中心面板节点的远程 3x-ui 面板。所有端点均位于 /panel/api/nodes 之下。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
List every configured node with its connection details, health, and last
heartbeat patch.
url: >-
#list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
- depth: 2
title: >-
This panel's node-auth CA certificate (public, PEM) to paste into a
node's mTLS trust setting. Lazily mints the CA and the master client
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
url: >-
#this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
- depth: 2
title: >-
Set the CA certificate this panel trusts for incoming node-API client
certificates (this panel acting as a node). Paste the managing panel's
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty value
must be a PEM certificate. Applied on the next panel restart.
url: >-
#set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
- depth: 2
title: Fetch a single node by ID.
url: '#fetch-a-single-node-by-id'
- depth: 2
title: >-
Fetch a node's own web TLS certificate/key file paths (proxied to the
node). Used by the inbound form's "Set Cert from Panel" so a
node-assigned inbound gets paths that exist on the node, not the central
panel.
url: >-
#fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
- depth: 2
title: >-
Register a new remote node. Provide its URL, apiToken, and optional
remark / allowPrivateAddress flag.
url: >-
#register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
- depth: 2
title: Replace a nodes connection details. Same body shape as /add.
url: '#replace-a-nodes-connection-details-same-body-shape-as-add'
- depth: 2
title: Delete a node. Inbounds bound to it are not auto-migrated.
url: '#delete-a-node-inbounds-bound-to-it-are-not-auto-migrated'
- depth: 2
title: Pause or resume traffic sync with this node.
url: '#pause-or-resume-traffic-sync-with-this-node'
- depth: 2
title: >-
Probe a node without saving it. Uses the body as connection details and
returns the same heartbeat snapshot a registered node would have.
url: >-
#probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
- depth: 2
title: >-
Connect to the node over HTTPS without verifying its certificate and
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
Node dialog to fetch and pin a self-signed certificate. Uses the same
body as /test.
url: >-
#connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
- depth: 2
title: >-
Use unsaved node connection details to list the remote inbounds
available for selective import.
url: >-
#use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
- depth: 2
title: Probe an existing node, updating its cached health state.
url: '#probe-an-existing-node-updating-its-cached-health-state'
- depth: 2
title: >-
Trigger the official panel self-updater on each given node (downloads
the latest release and restarts). Only enabled, online nodes are
updated; offline/disabled ones are reported as skipped. Set "dev": true
to move the nodes to the rolling per-commit dev channel instead of the
latest stable release. Returns a per-node result list.
url: >-
#trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
- depth: 2
title: >-
Aggregated metric history for a node — same shape as /server/history,
scoped to one node.
url: >-
#aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
structuredData:
headings:
- content: >-
List every configured node with its connection details, health, and
last heartbeat patch.
id: >-
list-every-configured-node-with-its-connection-details-health-and-last-heartbeat-patch
- content: >-
This panel's node-auth CA certificate (public, PEM) to paste into a
node's mTLS trust setting. Lazily mints the CA and the master client
cert on first call. Pair with setting tlsVerifyMode=mtls on the node.
id: >-
this-panels-node-auth-ca-certificate-public-pem-to-paste-into-a-nodes-mtls-trust-setting-lazily-mints-the-ca-and-the-master-client-cert-on-first-call-pair-with-setting-tlsverifymodemtls-on-the-node
- content: >-
Set the CA certificate this panel trusts for incoming node-API client
certificates (this panel acting as a node). Paste the managing panel's
CA (from nodes/mtls/ca). An empty caCert disables it. A non-empty
value must be a PEM certificate. Applied on the next panel restart.
id: >-
set-the-ca-certificate-this-panel-trusts-for-incoming-node-api-client-certificates-this-panel-acting-as-a-node-paste-the-managing-panels-ca-from-nodesmtlsca-an-empty-cacert-disables-it-a-non-empty-value-must-be-a-pem-certificate-applied-on-the-next-panel-restart
- content: Fetch a single node by ID.
id: fetch-a-single-node-by-id
- content: >-
Fetch a node's own web TLS certificate/key file paths (proxied to the
node). Used by the inbound form's "Set Cert from Panel" so a
node-assigned inbound gets paths that exist on the node, not the
central panel.
id: >-
fetch-a-nodes-own-web-tls-certificatekey-file-paths-proxied-to-the-node-used-by-the-inbound-forms-set-cert-from-panel-so-a-node-assigned-inbound-gets-paths-that-exist-on-the-node-not-the-central-panel
- content: >-
Register a new remote node. Provide its URL, apiToken, and optional
remark / allowPrivateAddress flag.
id: >-
register-a-new-remote-node-provide-its-url-apitoken-and-optional-remark--allowprivateaddress-flag
- content: Replace a nodes connection details. Same body shape as /add.
id: replace-a-nodes-connection-details-same-body-shape-as-add
- content: Delete a node. Inbounds bound to it are not auto-migrated.
id: delete-a-node-inbounds-bound-to-it-are-not-auto-migrated
- content: Pause or resume traffic sync with this node.
id: pause-or-resume-traffic-sync-with-this-node
- content: >-
Probe a node without saving it. Uses the body as connection details
and returns the same heartbeat snapshot a registered node would have.
id: >-
probe-a-node-without-saving-it-uses-the-body-as-connection-details-and-returns-the-same-heartbeat-snapshot-a-registered-node-would-have
- content: >-
Connect to the node over HTTPS without verifying its certificate and
return the leaf certificate's SHA-256 (base64). Used by the Add/Edit
Node dialog to fetch and pin a self-signed certificate. Uses the same
body as /test.
id: >-
connect-to-the-node-over-https-without-verifying-its-certificate-and-return-the-leaf-certificates-sha-256-base64-used-by-the-addedit-node-dialog-to-fetch-and-pin-a-self-signed-certificate-uses-the-same-body-as-test
- content: >-
Use unsaved node connection details to list the remote inbounds
available for selective import.
id: >-
use-unsaved-node-connection-details-to-list-the-remote-inbounds-available-for-selective-import
- content: Probe an existing node, updating its cached health state.
id: probe-an-existing-node-updating-its-cached-health-state
- content: >-
Trigger the official panel self-updater on each given node (downloads
the latest release and restarts). Only enabled, online nodes are
updated; offline/disabled ones are reported as skipped. Set "dev":
true to move the nodes to the rolling per-commit dev channel instead
of the latest stable release. Returns a per-node result list.
id: >-
trigger-the-official-panel-self-updater-on-each-given-node-downloads-the-latest-release-and-restarts-only-enabled-online-nodes-are-updated-offlinedisabled-ones-are-reported-as-skipped-set-dev-true-to-move-the-nodes-to-the-rolling-per-commit-dev-channel-instead-of-the-latest-stable-release-returns-a-per-node-result-list
- content: >-
Aggregated metric history for a node — same shape as /server/history,
scoped to one node.
id: >-
aggregated-metric-history-for-a-node--same-shape-as-serverhistory-scoped-to-one-node
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/nodes/list","method":"get"},{"path":"/panel/api/nodes/mtls/ca","method":"post"},{"path":"/panel/api/nodes/mtls/trustCA","method":"post"},{"path":"/panel/api/nodes/get/{id}","method":"get"},{"path":"/panel/api/nodes/webCert/{id}","method":"get"},{"path":"/panel/api/nodes/add","method":"post"},{"path":"/panel/api/nodes/update/{id}","method":"post"},{"path":"/panel/api/nodes/del/{id}","method":"post"},{"path":"/panel/api/nodes/setEnable/{id}","method":"post"},{"path":"/panel/api/nodes/test","method":"post"},{"path":"/panel/api/nodes/certFingerprint","method":"post"},{"path":"/panel/api/nodes/inbounds","method":"post"},{"path":"/panel/api/nodes/probe/{id}","method":"post"},{"path":"/panel/api/nodes/updatePanel","method":"post"},{"path":"/panel/api/nodes/history/{id}/{metric}/{bucket}","method":"get"}]} showTitle />
</>
);
}
@@ -0,0 +1,381 @@
---
title: 服务器
description: >-
系统状态、日志获取、证书生成器、Xray 二进制文件管理以及备份/恢复。所有接口均位于
/panel/api/server 下。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
averages, open connections, Xray state. Cached and refreshed every 2
seconds in the background.
url: >-
#real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
- depth: 2
title: >-
Reports whether per-client IP limits can be enforced on this host. The
panel uses it to gate the "IP Limit" field, since enforcement depends on
Fail2ban being installed.
url: >-
#reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
- depth: 2
title: >-
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead — same
data with a uniform {t, v} shape.
url: >-
#legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
- depth: 2
title: >-
Aggregated time-series for one metric. Returns an array of {t, v}
samples covering the last ~6 hours.
url: >-
#aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
- depth: 2
title: >-
Xray runtime metrics state — whether the xray config has a `metrics`
block, which expvar keys are flowing, and the current snapshot values
for each. Returns an empty state when metrics are not configured.
url: >-
#xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
- depth: 2
title: >-
Time-series history for one Xray runtime metric over the last ~6 hours.
Same {t, v} shape as /history/:metric/:bucket.
url: >-
#time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
- depth: 2
title: >-
Latest snapshot from the Xray observatory — per-outbound latency, health
status, and last-probe time. Only populated when the Xray config has an
observatory configured.
url: >-
#latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
- depth: 2
title: >-
Time-series of observatory probe results for one outbound tag. Same {t,
v} shape as the other history endpoints.
url: >-
#time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
- depth: 2
title: List Xray binary versions available for install on this host.
url: '#list-xray-binary-versions-available-for-install-on-this-host'
- depth: 2
title: Check whether a newer 3x-ui release is available on GitHub.
url: '#check-whether-a-newer-3x-ui-release-is-available-on-github'
- depth: 2
title: Return the assembled Xray config thats currently running on this host.
url: '#return-the-assembled-xray-config-thats-currently-running-on-this-host'
- depth: 2
title: >-
Stream the SQLite database file as an attachment. Use as a manual
backup.
url: '#stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup'
- depth: 2
title: >-
Stream a cross-engine migration file as an attachment: a .dump (SQL
text) on SQLite, or a .db SQLite database built from the live data on
PostgreSQL.
url: >-
#stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
- depth: 2
title: Generate a fresh UUID v4. Convenience helper for client IDs.
url: '#generate-a-fresh-uuid-v4-convenience-helper-for-client-ids'
- depth: 2
title: >-
Return this panel's own web TLS certificate and key file paths. The
central panel calls it on a node (via the node API token) so "Set Cert
from Panel" fills a node-assigned inbound with paths that exist on the
node.
url: >-
#return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
- depth: 2
title: >-
Read-only summaries (guid, parentGuid, name, address, status, versions)
of the nodes this panel manages. A parent panel calls it on a node (via
the node API token) to surface transitive sub-nodes in a chained
topology. Counts are computed by the parent, not returned here.
url: >-
#read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
- depth: 2
title: Generate a new X25519 keypair for Reality.
url: '#generate-a-new-x25519-keypair-for-reality'
- depth: 2
title: >-
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
{privateKey, publicKey, seed}.
url: >-
#generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
- depth: 2
title: >-
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
{clientKey, serverKey}.
url: >-
#generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
- depth: 2
title: >-
Generate VLESS encryption auth options. Returns an auths array each with
id, label, encryption, and decryption fields.
url: >-
#generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
- depth: 2
title: Stop the Xray binary. All proxies go offline immediately.
url: '#stop-the-xray-binary-all-proxies-go-offline-immediately'
- depth: 2
title: >-
Reload Xray with the current config. Typically required after structural
inbound or routing changes.
url: >-
#reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
- depth: 2
title: >-
Download and install the specified Xray version. Pass "latest" for the
newest release.
url: >-
#download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
- depth: 2
title: >-
Self-update the panel to the latest version. The server restarts on
success.
url: >-
#self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
- depth: 2
title: >-
Toggle the panel update channel between stable and the rolling
per-commit dev release. Only effective on dev builds.
url: >-
#toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
- depth: 2
title: >-
Refresh the default GeoIP / GeoSite data files. Body can include a
fileName, or use the /:fileName variant.
url: >-
#refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
- depth: 2
title: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
url: '#refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat'
- depth: 2
title: Return the last N lines of the panels own log.
url: '#return-the-last-n-lines-of-the-panels-own-log'
- depth: 2
title: Return the last N lines of the Xray process log.
url: '#return-the-last-n-lines-of-the-xray-process-log'
- depth: 2
title: >-
Restore the panel DB from an uploaded SQLite file (multipart form, field
name "db"). The panel restarts after restore. Destructive.
url: >-
#restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
- depth: 2
title: >-
Generate a new ECH (Encrypted Client Hello) keypair and config list for
the given SNI.
url: >-
#generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
- depth: 2
title: >-
Compute the hex SHA-256 of a certificate (DER) for pinning
(pinnedPeerCertSha256). Provide either a server file path or inline
PEM/DER content.
url: >-
#compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
- depth: 2
title: >-
Run `xray tls ping` against a remote server and return its live
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
url: >-
#run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
- depth: 2
title: >-
Fetch the fully aggregated inbound_client_ips database table. Used by
nodes to sync recently active IPs across the cluster.
url: >-
#fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
- depth: 2
title: >-
Submit a list of recently active IP timestamps. The panel merges them
with the existing database to maintain a unified global IP-limit view.
url: >-
#submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
structuredData:
headings:
- content: >-
Real-time machine snapshot: CPU, memory, swap, disk, network IO, load
averages, open connections, Xray state. Cached and refreshed every 2
seconds in the background.
id: >-
real-time-machine-snapshot-cpu-memory-swap-disk-network-io-load-averages-open-connections-xray-state-cached-and-refreshed-every-2-seconds-in-the-background
- content: >-
Reports whether per-client IP limits can be enforced on this host. The
panel uses it to gate the "IP Limit" field, since enforcement depends
on Fail2ban being installed.
id: >-
reports-whether-per-client-ip-limits-can-be-enforced-on-this-host-the-panel-uses-it-to-gate-the-ip-limit-field-since-enforcement-depends-on-fail2ban-being-installed
- content: >-
Legacy: aggregated CPU history. Use /history/cpu/:bucket instead —
same data with a uniform {t, v} shape.
id: >-
legacy-aggregated-cpu-history-use-historycpubucket-instead--same-data-with-a-uniform-t-v-shape
- content: >-
Aggregated time-series for one metric. Returns an array of {t, v}
samples covering the last ~6 hours.
id: >-
aggregated-time-series-for-one-metric-returns-an-array-of-t-v-samples-covering-the-last-6-hours
- content: >-
Xray runtime metrics state — whether the xray config has a `metrics`
block, which expvar keys are flowing, and the current snapshot values
for each. Returns an empty state when metrics are not configured.
id: >-
xray-runtime-metrics-state--whether-the-xray-config-has-a-metrics-block-which-expvar-keys-are-flowing-and-the-current-snapshot-values-for-each-returns-an-empty-state-when-metrics-are-not-configured
- content: >-
Time-series history for one Xray runtime metric over the last ~6
hours. Same {t, v} shape as /history/:metric/:bucket.
id: >-
time-series-history-for-one-xray-runtime-metric-over-the-last-6-hours-same-t-v-shape-as-historymetricbucket
- content: >-
Latest snapshot from the Xray observatory — per-outbound latency,
health status, and last-probe time. Only populated when the Xray
config has an observatory configured.
id: >-
latest-snapshot-from-the-xray-observatory--per-outbound-latency-health-status-and-last-probe-time-only-populated-when-the-xray-config-has-an-observatory-configured
- content: >-
Time-series of observatory probe results for one outbound tag. Same
{t, v} shape as the other history endpoints.
id: >-
time-series-of-observatory-probe-results-for-one-outbound-tag-same-t-v-shape-as-the-other-history-endpoints
- content: List Xray binary versions available for install on this host.
id: list-xray-binary-versions-available-for-install-on-this-host
- content: Check whether a newer 3x-ui release is available on GitHub.
id: check-whether-a-newer-3x-ui-release-is-available-on-github
- content: >-
Return the assembled Xray config thats currently running on this
host.
id: return-the-assembled-xray-config-thats-currently-running-on-this-host
- content: >-
Stream the SQLite database file as an attachment. Use as a manual
backup.
id: >-
stream-the-sqlite-database-file-as-an-attachment-use-as-a-manual-backup
- content: >-
Stream a cross-engine migration file as an attachment: a .dump (SQL
text) on SQLite, or a .db SQLite database built from the live data on
PostgreSQL.
id: >-
stream-a-cross-engine-migration-file-as-an-attachment-a-dump-sql-text-on-sqlite-or-a-db-sqlite-database-built-from-the-live-data-on-postgresql
- content: Generate a fresh UUID v4. Convenience helper for client IDs.
id: generate-a-fresh-uuid-v4-convenience-helper-for-client-ids
- content: >-
Return this panel's own web TLS certificate and key file paths. The
central panel calls it on a node (via the node API token) so "Set Cert
from Panel" fills a node-assigned inbound with paths that exist on the
node.
id: >-
return-this-panels-own-web-tls-certificate-and-key-file-paths-the-central-panel-calls-it-on-a-node-via-the-node-api-token-so-set-cert-from-panel-fills-a-node-assigned-inbound-with-paths-that-exist-on-the-node
- content: >-
Read-only summaries (guid, parentGuid, name, address, status,
versions) of the nodes this panel manages. A parent panel calls it on
a node (via the node API token) to surface transitive sub-nodes in a
chained topology. Counts are computed by the parent, not returned
here.
id: >-
read-only-summaries-guid-parentguid-name-address-status-versions-of-the-nodes-this-panel-manages-a-parent-panel-calls-it-on-a-node-via-the-node-api-token-to-surface-transitive-sub-nodes-in-a-chained-topology-counts-are-computed-by-the-parent-not-returned-here
- content: Generate a new X25519 keypair for Reality.
id: generate-a-new-x25519-keypair-for-reality
- content: >-
Generate a new ML-DSA-65 keypair (post-quantum signature). Returns
{privateKey, publicKey, seed}.
id: >-
generate-a-new-ml-dsa-65-keypair-post-quantum-signature-returns-privatekey-publickey-seed
- content: >-
Generate a new ML-KEM-768 keypair (post-quantum KEM). Returns
{clientKey, serverKey}.
id: >-
generate-a-new-ml-kem-768-keypair-post-quantum-kem-returns-clientkey-serverkey
- content: >-
Generate VLESS encryption auth options. Returns an auths array each
with id, label, encryption, and decryption fields.
id: >-
generate-vless-encryption-auth-options-returns-an-auths-array-each-with-id-label-encryption-and-decryption-fields
- content: Stop the Xray binary. All proxies go offline immediately.
id: stop-the-xray-binary-all-proxies-go-offline-immediately
- content: >-
Reload Xray with the current config. Typically required after
structural inbound or routing changes.
id: >-
reload-xray-with-the-current-config-typically-required-after-structural-inbound-or-routing-changes
- content: >-
Download and install the specified Xray version. Pass "latest" for the
newest release.
id: >-
download-and-install-the-specified-xray-version-pass-latest-for-the-newest-release
- content: >-
Self-update the panel to the latest version. The server restarts on
success.
id: >-
self-update-the-panel-to-the-latest-version-the-server-restarts-on-success
- content: >-
Toggle the panel update channel between stable and the rolling
per-commit dev release. Only effective on dev builds.
id: >-
toggle-the-panel-update-channel-between-stable-and-the-rolling-per-commit-dev-release-only-effective-on-dev-builds
- content: >-
Refresh the default GeoIP / GeoSite data files. Body can include a
fileName, or use the /:fileName variant.
id: >-
refresh-the-default-geoip--geosite-data-files-body-can-include-a-filename-or-use-the-filename-variant
- content: Refresh a single Geo file by filename (e.g. geoip.dat, geosite.dat).
id: refresh-a-single-geo-file-by-filename-eg-geoipdat-geositedat
- content: Return the last N lines of the panels own log.
id: return-the-last-n-lines-of-the-panels-own-log
- content: Return the last N lines of the Xray process log.
id: return-the-last-n-lines-of-the-xray-process-log
- content: >-
Restore the panel DB from an uploaded SQLite file (multipart form,
field name "db"). The panel restarts after restore. Destructive.
id: >-
restore-the-panel-db-from-an-uploaded-sqlite-file-multipart-form-field-name-db-the-panel-restarts-after-restore-destructive
- content: >-
Generate a new ECH (Encrypted Client Hello) keypair and config list
for the given SNI.
id: >-
generate-a-new-ech-encrypted-client-hello-keypair-and-config-list-for-the-given-sni
- content: >-
Compute the hex SHA-256 of a certificate (DER) for pinning
(pinnedPeerCertSha256). Provide either a server file path or inline
PEM/DER content.
id: >-
compute-the-hex-sha-256-of-a-certificate-der-for-pinning-pinnedpeercertsha256-provide-either-a-server-file-path-or-inline-pemder-content
- content: >-
Run `xray tls ping` against a remote server and return its live
leaf-certificate SHA-256 hash(es) for pinning (pinnedPeerCertSha256).
id: >-
run-xray-tls-ping-against-a-remote-server-and-return-its-live-leaf-certificate-sha-256-hashes-for-pinning-pinnedpeercertsha256
- content: >-
Fetch the fully aggregated inbound_client_ips database table. Used by
nodes to sync recently active IPs across the cluster.
id: >-
fetch-the-fully-aggregated-inbound_client_ips-database-table-used-by-nodes-to-sync-recently-active-ips-across-the-cluster
- content: >-
Submit a list of recently active IP timestamps. The panel merges them
with the existing database to maintain a unified global IP-limit view.
id: >-
submit-a-list-of-recently-active-ip-timestamps-the-panel-merges-them-with-the-existing-database-to-maintain-a-unified-global-ip-limit-view
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/server/status","method":"get"},{"path":"/panel/api/server/fail2banStatus","method":"get"},{"path":"/panel/api/server/cpuHistory/{bucket}","method":"get"},{"path":"/panel/api/server/history/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayMetricsState","method":"get"},{"path":"/panel/api/server/xrayMetricsHistory/{metric}/{bucket}","method":"get"},{"path":"/panel/api/server/xrayObservatory","method":"get"},{"path":"/panel/api/server/xrayObservatoryHistory/{tag}/{bucket}","method":"get"},{"path":"/panel/api/server/getXrayVersion","method":"get"},{"path":"/panel/api/server/getPanelUpdateInfo","method":"get"},{"path":"/panel/api/server/getConfigJson","method":"get"},{"path":"/panel/api/server/getDb","method":"get"},{"path":"/panel/api/server/getMigration","method":"get"},{"path":"/panel/api/server/getNewUUID","method":"get"},{"path":"/panel/api/server/getWebCertFiles","method":"get"},{"path":"/panel/api/server/descendants","method":"get"},{"path":"/panel/api/server/getNewX25519Cert","method":"get"},{"path":"/panel/api/server/getNewmldsa65","method":"get"},{"path":"/panel/api/server/getNewmlkem768","method":"get"},{"path":"/panel/api/server/getNewVlessEnc","method":"get"},{"path":"/panel/api/server/stopXrayService","method":"post"},{"path":"/panel/api/server/restartXrayService","method":"post"},{"path":"/panel/api/server/installXray/{version}","method":"post"},{"path":"/panel/api/server/updatePanel","method":"post"},{"path":"/panel/api/server/setUpdateChannel","method":"post"},{"path":"/panel/api/server/updateGeofile","method":"post"},{"path":"/panel/api/server/updateGeofile/{fileName}","method":"post"},{"path":"/panel/api/server/logs/{count}","method":"post"},{"path":"/panel/api/server/xraylogs/{count}","method":"post"},{"path":"/panel/api/server/importDB","method":"post"},{"path":"/panel/api/server/getNewEchCert","method":"post"},{"path":"/panel/api/server/getCertHash","method":"post"},{"path":"/panel/api/server/getRemoteCertHash","method":"post"},{"path":"/panel/api/server/clientIps","method":"get"},{"path":"/panel/api/server/clientIps","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,101 @@
---
title: 设置
description: >-
面板配置与用户凭据。所有端点均位于 /panel/api/setting 之下,需要已登录的会话或 Bearer 令牌。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
返回每一项面板设置:Web 服务器、Telegram 机器人、订阅、安全、LDAP。即“设置”页面所编辑的完整 JSON
数据。
url: >-
#return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
- depth: 2
title: >-
根据请求主机返回计算得出的默认设置。可用于预览全新安装将采用的配置。
url: >-
#return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
- depth: 2
title: >-
一次性保存全部设置。请求体与 /all 返回的结构一致。无效值(端口错误、证书对缺失等)会在写入前被拒绝。
url: >-
#persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
- depth: 2
title: >-
更改面板管理员的用户名和密码。需要提供当前凭据以供验证。成功后会话将以新值刷新。
url: >-
#change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
- depth: 2
title: >-
在 3 秒缓冲期后重启整个 3x-ui 进程。连接会立即断开;面板将在约 5-10 秒后重新上线。
url: >-
#restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
- depth: 2
title: >-
测试 SMTP 连接,并按阶段(连接、认证、发送)逐步报告。返回包含阶段和消息的结构化结果。
url: >-
#test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
- depth: 2
title: >-
通过向已配置的聊天发送一条测试消息来测试 Telegram 机器人连接。
url: >-
#test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
- depth: 2
title: >-
返回随此面板版本一同提供的内置默认 Xray JSON 配置模板。
url: >-
#return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
structuredData:
headings:
- content: >-
返回每一项面板设置:Web 服务器、Telegram 机器人、订阅、安全、LDAP。即“设置”页面所编辑的完整 JSON
数据。
id: >-
return-every-panel-setting-web-server-telegram-bot-subscription-security-ldap-the-full-json-blob-that-the-settings-page-edits
- content: >-
根据请求主机返回计算得出的默认设置。可用于预览全新安装将采用的配置。
id: >-
return-the-computed-default-settings-based-on-the-request-host-useful-to-preview-what-a-fresh-install-would-use
- content: >-
一次性保存全部设置。请求体与 /all 返回的结构一致。无效值(端口错误、证书对缺失等)会在写入前被拒绝。
id: >-
persist-every-setting-at-once-the-body-mirrors-the-shape-returned-by-all-invalid-values-bad-ports-missing-cert-pairs-etc-are-rejected-before-write
- content: >-
更改面板管理员的用户名和密码。需要提供当前凭据以供验证。成功后会话将以新值刷新。
id: >-
change-the-panel-admin-username-and-password-requires-the-current-credentials-for-verification-the-session-is-refreshed-with-the-new-values-on-success
- content: >-
在 3 秒缓冲期后重启整个 3x-ui 进程。连接会立即断开;面板将在约 5-10 秒后重新上线。
id: >-
restart-the-entire-3x-ui-process-after-a-3-second-grace-period-the-connection-drops-immediately-the-panel-comes-back-online-5-10-seconds-later
- content: >-
测试 SMTP 连接,并按阶段(连接、认证、发送)逐步报告。返回包含阶段和消息的结构化结果。
id: >-
test-smtp-connection-with-stage-by-stage-reporting-connect-auth-send-returns-structured-result-with-stage-and-message
- content: >-
通过向已配置的聊天发送一条测试消息来测试 Telegram 机器人连接。
id: >-
test-telegram-bot-connection-by-sending-a-test-message-to-the-configured-chat
- content: >-
返回随此面板版本一同提供的内置默认 Xray JSON 配置模板。
id: >-
return-the-built-in-default-xray-json-config-template-that-ships-with-this-panel-version
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/setting/all","method":"post"},{"path":"/panel/api/setting/defaultSettings","method":"post"},{"path":"/panel/api/setting/update","method":"post"},{"path":"/panel/api/setting/updateUser","method":"post"},{"path":"/panel/api/setting/restartPanel","method":"post"},{"path":"/panel/api/setting/testSmtp","method":"post"},{"path":"/panel/api/setting/testTgBot","method":"post"},{"path":"/panel/api/setting/getDefaultJsonConfig","method":"get"}]} showTitle />
</>
);
}
@@ -0,0 +1,59 @@
---
title: 订阅服务器
description: >-
一个独立的 HTTP/HTTPS 服务器,用于向客户端提供代理订阅链接(标准、JSON 和 Clash)。该服务器监听自己的端口(默认
10882),并在“设置 → 订阅”中进行配置。路径可自定义;下方展示的是默认值。所有订阅端点都会设置响应头,供客户端应用读取流量/到期信息。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
返回与该订阅 ID 匹配的所有已启用客户端的 base64 编码订阅链接。当请求带有 Accept: text/html
头或 ?html=1 时,改为渲染一个带样式的信息页面。默认路径:/sub/:subid。
url: >-
#return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
- depth: 2
title: >-
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。默认路径:/json/:subid。
url: >-
#return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
- depth: 2
title: >-
以兼容 Clash/Mihomo 的 YAML 配置形式返回订阅,其中包含已配置的全局 Clash 路由规则。仅在设置中启用 Clash
订阅时可用。默认路径:/clash/:subid。
url: >-
#return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
structuredData:
headings:
- content: >-
返回与该订阅 ID 匹配的所有已启用客户端的 base64 编码订阅链接。当请求带有 Accept:
text/html 头或 ?html=1 时,改为渲染一个带样式的信息页面。默认路径:/sub/:subid。
id: >-
return-base64-encoded-subscription-links-for-all-enabled-clients-matching-the-subscription-id-when-the-request-has-an-accept-texthtml-header-or-html1-renders-a-styled-info-page-instead-default-path-subsubid
- content: >-
以代理配置的 JSON 数组形式返回订阅(每个已启用客户端一项)。仅在设置中启用 JSON 订阅时可用。默认路径:/json/:subid。
id: >-
return-subscription-as-a-json-array-of-proxy-configs-one-per-enabled-client-only-when-json-subscription-is-enabled-in-settings-default-path-jsonsubid
- content: >-
以兼容 Clash/Mihomo 的 YAML 配置形式返回订阅,其中包含已配置的全局 Clash 路由规则。仅在设置中启用 Clash
订阅时可用。默认路径:/clash/:subid。
id: >-
return-subscription-as-a-clashmihomo-compatible-yaml-config-including-configured-global-clash-routing-rules-only-when-clash-subscription-is-enabled-in-settings-default-path-clashsubid
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/{subPath}{subid}","method":"get"},{"path":"/{jsonPath}{subid}","method":"get"},{"path":"/{clashPath}{subid}","method":"get"}]} showTitle />
</>
);
}
@@ -0,0 +1,44 @@
---
title: WebSocket
description: >-
通过 WebSocket 获取实时状态更新。只需在
<code>ws://<panel>/ws</code> 建立一次连接,即可接收 JSON 消息流,无需轮询。需要经过身份验证的会话
Cookie(不支持 Bearer token 身份验证)。每条消息都带有一个 <code>type</code> 字段,用于标识其载荷结构。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
session cookie (Bearer token auth is not supported here). Returns 101
Switching Protocols on success. The server then pushes JSON messages
described below.
url: >-
#upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
structuredData:
headings:
- content: >-
Upgrade an HTTP connection to a WebSocket. Requires an authenticated
session cookie (Bearer token auth is not supported here). Returns 101
Switching Protocols on success. The server then pushes JSON messages
described below.
id: >-
upgrade-an-http-connection-to-a-websocket-requires-an-authenticated-session-cookie-bearer-token-auth-is-not-supported-here-returns-101-switching-protocols-on-success-the-server-then-pushes-json-messages-described-below
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/ws","method":"get"}]} showTitle />
</>
);
}
@@ -0,0 +1,257 @@
---
title: Xray 设置
description: >-
Xray 配置模板、出站管理、Warp/Nord 集成以及配置测试。所有端点均位于 /panel/api/xray
下。
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: >-
Return the Xray config template (JSON string), available inbound tags,
client reverse tags, and the configured outbound test URL in one
response.
url: >-
#return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
- depth: 2
title: >-
Return the built-in default Xray config shipped with the panel
(identical to /panel/api/setting/getDefaultJsonConfig).
url: >-
#return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
- depth: 2
title: >-
Return traffic statistics for every outbound. Each outbound shows
up/down/total counters.
url: >-
#return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
- depth: 2
title: >-
Return the most recent Xray process stdout/stderr output. Useful to
check for startup errors or runtime warnings.
url: >-
#return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
- depth: 2
title: >-
Save the Xray JSON config template and optionally the outbound test URL.
Both are sent as form fields.
url: >-
#save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
- depth: 2
title: >-
Manage Cloudflare Warp integration. The action parameter selects the
operation.
url: >-
#manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
- depth: 2
title: Manage NordVPN integration. The action parameter selects the operation.
url: '#manage-nordvpn-integration-the-action-parameter-selects-the-operation'
- depth: 2
title: Reset traffic counters for a specific outbound by tag.
url: '#reset-traffic-counters-for-a-specific-outbound-by-tag'
- depth: 2
title: >-
Test an outbound configuration. Sends the outbound JSON (required),
optionally all outbounds (to resolve sockopt.dialerProxy dependencies),
and a mode flag.
url: >-
#test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
- depth: 2
title: >-
Test a batch of outbounds (max 50) through one shared temp xray
instance. Returns an array of results in input order, each with the
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
breakdown.
url: >-
#test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
- depth: 2
title: >-
Live state of routing balancers in the running core
(RoutingService.GetBalancerInfo): current override and the targets the
strategy prefers. Returns a map keyed by balancer tag.
url: >-
#live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
- depth: 2
title: >-
Force a balancer in the running core to always pick one outbound
(RoutingService.OverrideBalancerTarget). Applied live without a restart;
cleared automatically when Xray restarts.
url: >-
#force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
- depth: 2
title: >-
Ask the running core which outbound its router would pick for a
synthetic connection (RoutingService.TestRoute). No traffic is sent.
url: >-
#ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
- depth: 2
title: >-
List all outbound subscriptions (remote URLs that supply additional
outbounds), newest first.
url: >-
#list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
- depth: 2
title: >-
Create an outbound subscription. The URL is fetched, parsed into
outbounds with stable tags, and merged additively into the running Xray
config.
url: >-
#create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
- depth: 2
title: >-
Update an existing outbound subscription by id. Accepts the same form
fields as create.
url: >-
#update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
- depth: 2
title: Delete an outbound subscription by id.
url: '#delete-an-outbound-subscription-by-id'
- depth: 2
title: >-
Delete an outbound subscription by id (POST alias of DELETE for
axios-friendly clients).
url: >-
#delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
- depth: 2
title: >-
Force an immediate re-fetch of the subscription and return the parsed
outbounds. Signals Xray to reload.
url: >-
#force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
- depth: 2
title: >-
Reorder a subscription one step up or down in priority (controls its
position in the merged outbounds).
url: >-
#reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
- depth: 2
title: >-
Preview a subscription URL: fetch and parse it into outbounds without
persisting anything.
url: >-
#preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
structuredData:
headings:
- content: >-
Return the Xray config template (JSON string), available inbound tags,
client reverse tags, and the configured outbound test URL in one
response.
id: >-
return-the-xray-config-template-json-string-available-inbound-tags-client-reverse-tags-and-the-configured-outbound-test-url-in-one-response
- content: >-
Return the built-in default Xray config shipped with the panel
(identical to /panel/api/setting/getDefaultJsonConfig).
id: >-
return-the-built-in-default-xray-config-shipped-with-the-panel-identical-to-panelapisettinggetdefaultjsonconfig
- content: >-
Return traffic statistics for every outbound. Each outbound shows
up/down/total counters.
id: >-
return-traffic-statistics-for-every-outbound-each-outbound-shows-updowntotal-counters
- content: >-
Return the most recent Xray process stdout/stderr output. Useful to
check for startup errors or runtime warnings.
id: >-
return-the-most-recent-xray-process-stdoutstderr-output-useful-to-check-for-startup-errors-or-runtime-warnings
- content: >-
Save the Xray JSON config template and optionally the outbound test
URL. Both are sent as form fields.
id: >-
save-the-xray-json-config-template-and-optionally-the-outbound-test-url-both-are-sent-as-form-fields
- content: >-
Manage Cloudflare Warp integration. The action parameter selects the
operation.
id: >-
manage-cloudflare-warp-integration-the-action-parameter-selects-the-operation
- content: >-
Manage NordVPN integration. The action parameter selects the
operation.
id: manage-nordvpn-integration-the-action-parameter-selects-the-operation
- content: Reset traffic counters for a specific outbound by tag.
id: reset-traffic-counters-for-a-specific-outbound-by-tag
- content: >-
Test an outbound configuration. Sends the outbound JSON (required),
optionally all outbounds (to resolve sockopt.dialerProxy
dependencies), and a mode flag.
id: >-
test-an-outbound-configuration-sends-the-outbound-json-required-optionally-all-outbounds-to-resolve-sockoptdialerproxy-dependencies-and-a-mode-flag
- content: >-
Test a batch of outbounds (max 50) through one shared temp xray
instance. Returns an array of results in input order, each with the
outbound tag, delay, HTTP status and a connect/TLS/TTFB timing
breakdown.
id: >-
test-a-batch-of-outbounds-max-50-through-one-shared-temp-xray-instance-returns-an-array-of-results-in-input-order-each-with-the-outbound-tag-delay-http-status-and-a-connecttlsttfb-timing-breakdown
- content: >-
Live state of routing balancers in the running core
(RoutingService.GetBalancerInfo): current override and the targets the
strategy prefers. Returns a map keyed by balancer tag.
id: >-
live-state-of-routing-balancers-in-the-running-core-routingservicegetbalancerinfo-current-override-and-the-targets-the-strategy-prefers-returns-a-map-keyed-by-balancer-tag
- content: >-
Force a balancer in the running core to always pick one outbound
(RoutingService.OverrideBalancerTarget). Applied live without a
restart; cleared automatically when Xray restarts.
id: >-
force-a-balancer-in-the-running-core-to-always-pick-one-outbound-routingserviceoverridebalancertarget-applied-live-without-a-restart-cleared-automatically-when-xray-restarts
- content: >-
Ask the running core which outbound its router would pick for a
synthetic connection (RoutingService.TestRoute). No traffic is sent.
id: >-
ask-the-running-core-which-outbound-its-router-would-pick-for-a-synthetic-connection-routingservicetestroute-no-traffic-is-sent
- content: >-
List all outbound subscriptions (remote URLs that supply additional
outbounds), newest first.
id: >-
list-all-outbound-subscriptions-remote-urls-that-supply-additional-outbounds-newest-first
- content: >-
Create an outbound subscription. The URL is fetched, parsed into
outbounds with stable tags, and merged additively into the running
Xray config.
id: >-
create-an-outbound-subscription-the-url-is-fetched-parsed-into-outbounds-with-stable-tags-and-merged-additively-into-the-running-xray-config
- content: >-
Update an existing outbound subscription by id. Accepts the same form
fields as create.
id: >-
update-an-existing-outbound-subscription-by-id-accepts-the-same-form-fields-as-create
- content: Delete an outbound subscription by id.
id: delete-an-outbound-subscription-by-id
- content: >-
Delete an outbound subscription by id (POST alias of DELETE for
axios-friendly clients).
id: >-
delete-an-outbound-subscription-by-id-post-alias-of-delete-for-axios-friendly-clients
- content: >-
Force an immediate re-fetch of the subscription and return the parsed
outbounds. Signals Xray to reload.
id: >-
force-an-immediate-re-fetch-of-the-subscription-and-return-the-parsed-outbounds-signals-xray-to-reload
- content: >-
Reorder a subscription one step up or down in priority (controls its
position in the merged outbounds).
id: >-
reorder-a-subscription-one-step-up-or-down-in-priority-controls-its-position-in-the-merged-outbounds
- content: >-
Preview a subscription URL: fetch and parse it into outbounds without
persisting anything.
id: >-
preview-a-subscription-url-fetch-and-parse-it-into-outbounds-without-persisting-anything
contents: []
---
{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}
export default function Layout(props) {
const { APIPage, OpenAPIPage } = props.components ?? {};
// "APIPage" is the old name from v10, this allows both for backward compatibility
const Comp = OpenAPIPage ?? APIPage;
return (
<>
{props.children}
<Comp document="./public/openapi.json" webhooks={[]} operations={[{"path":"/panel/api/xray/","method":"post"},{"path":"/panel/api/xray/getDefaultJsonConfig","method":"get"},{"path":"/panel/api/xray/getOutboundsTraffic","method":"get"},{"path":"/panel/api/xray/getXrayResult","method":"get"},{"path":"/panel/api/xray/update","method":"post"},{"path":"/panel/api/xray/warp/{action}","method":"post"},{"path":"/panel/api/xray/nord/{action}","method":"post"},{"path":"/panel/api/xray/resetOutboundsTraffic","method":"post"},{"path":"/panel/api/xray/testOutbound","method":"post"},{"path":"/panel/api/xray/testOutbounds","method":"post"},{"path":"/panel/api/xray/balancerStatus","method":"post"},{"path":"/panel/api/xray/balancerOverride","method":"post"},{"path":"/panel/api/xray/routeTest","method":"post"},{"path":"/panel/api/xray/outbound-subs","method":"get"},{"path":"/panel/api/xray/outbound-subs","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}","method":"delete"},{"path":"/panel/api/xray/outbound-subs/{id}/del","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/refresh","method":"post"},{"path":"/panel/api/xray/outbound-subs/{id}/move","method":"post"},{"path":"/panel/api/xray/outbound-subs/parse","method":"post"}]} showTitle />
</>
);
}
@@ -0,0 +1,62 @@
---
title: 数据库
description: 3x-ui 的存储后端——SQLite(默认)与 PostgreSQL——涵盖数据库路径、连接池以及从 SQLite 到 PostgreSQL 的迁移。
icon: Database
---
3x-ui 将所有内容——入站、客户端、设置——都存储在数据库中。你在安装时
选择后端;两者都是一等支持。
## SQLite(默认)
位于 `/etc/x-ui/x-ui.db` 的单个文件。无需任何配置,适合中小型
部署。该文件夹可通过
[`XUI_DB_FOLDER`](/docs/reference/env-vars#database) 配置(在 Windows 上默认
紧挨着二进制文件存放)。
## PostgreSQL
推荐用于客户端数量庞大或多节点的部署。安装程序既可以为你在本地
安装 PostgreSQL,也可以接受指向现有服务器的 DSN。运行时通过环境变量
选择后端,安装程序会将这些变量写入 `/etc/default/x-ui`
```bash title="/etc/default/x-ui"
XUI_DB_TYPE=postgres
XUI_DB_DSN=postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable
```
使用 `XUI_DB_MAX_OPEN_CONNS` 和 `XUI_DB_MAX_IDLE_CONNS` 调优连接池。
### Docker
`docker compose up -d` 仍然使用 SQLite。若要配合内置的 PostgreSQL
服务运行,请取消 `docker-compose.yml` 中两行 `XUI_DB_*` 的注释,并使用
对应的 profile 启动:
```bash
docker compose --profile postgres up -d
```
## 从 SQLite 迁移到 PostgreSQL
使用内置命令将现有的 SQLite 安装迁移到 PostgreSQL
```bash
x-ui migrate-db --dsn "postgres://xui:password@127.0.0.1:5432/xui?sslmode=disable"
```
然后在 `/etc/default/x-ui` 中设置 `XUI_DB_TYPE` 和 `XUI_DB_DSN` 并重启:
```bash
systemctl restart x-ui
```
<Callout type="info">
源 SQLite 文件不会被改动——只有在你确认新后端正常工作后,才手动
将其删除。
</Callout>
## 备份
无论使用哪种后端,都要定期备份——参见
[备份与恢复](/docs/operations/backup-restore)。
@@ -0,0 +1,82 @@
---
title: 环境变量
description: 3x-ui 的 XUI_* 环境变量完整参考——涵盖数据库、面板、日志、内存以及隧道健康监测器。
icon: Variable
---
3x-ui 从 `XUI_*` 环境变量中读取其运行时配置。使用脚本安装时,安装程序会将
这些变量写入服务环境文件(`/etc/default/x-ui`,或视发行版而定的
`/etc/conf.d/x-ui` / `/etc/sysconfig/x-ui`);使用 Docker 时,则在
`docker-compose.yml` 或 `docker run -e` 中设置。默认值已足够合理——只需设置
你需要更改的项,然后重启即可:`systemctl restart x-ui`。
## 数据库
| Variable | Default | Description |
| ------------------------ | ----------- | -------------------------------------------------------------------- |
| `XUI_DB_TYPE` | `sqlite` | 后端:`sqlite`,或 `postgres`(也接受 `postgresql` / `pg`)。 |
| `XUI_DB_FOLDER` | `/etc/x-ui` | SQLite 数据库文件(`x-ui.db`)所在的文件夹。 |
| `XUI_DB_DSN` | — | PostgreSQL 连接字符串(当 `XUI_DB_TYPE=postgres` 时使用)。 |
| `XUI_DB_MAX_OPEN_CONNS` | — | PostgreSQL 连接池中的最大打开连接数。 |
| `XUI_DB_MAX_IDLE_CONNS` | — | PostgreSQL 连接池中的最大空闲连接数。 |
默认的 SQLite 数据库路径为 `/etc/x-ui/x-ui.db`。有关 SQLite ↔ PostgreSQL 的
细节,参见 [数据库](/docs/reference/database)。
## 面板
| Variable | Default | Description |
| ------------------------ | ------- | ------------------------------------------------------------------------ |
| `XUI_PORT` | — | 覆盖面板端口(1–65535)。优先级高于已存储的设置。 |
| `XUI_INIT_WEB_BASE_PATH` | `/` | **首次**启动时的初始 Web 根路径(例如 `/panel`)。 |
| `XUI_ENABLE_FAIL2BAN` | `true` | 启用基于 Fail2ban 的 IP 限制强制执行。 |
| `XUI_SKIP_HSTS` | `false` | 跳过 HSTS 标头——当 TLS 由反向代理终结时设为 `true`。 |
## 日志与二进制文件
| Variable | Default | Description |
| ---------------- | ---------------- | ----------------------------------------------------------- |
| `XUI_LOG_LEVEL` | `info` | `debug`、`info`、`notice`、`warning` 或 `error`。 |
| `XUI_DEBUG` | `false` | 调试模式(强制将日志级别设为 `debug`)。 |
| `XUI_LOG_FOLDER` | `/var/log/x-ui` | 日志输出目录。 |
| `XUI_BIN_FOLDER` | `bin` | 存放 Xray-core 二进制文件及 geosite/geoip 文件的文件夹。 |
## 内存与性能分析
面板通过 `GOGC` 和定期释放来保持低内存占用。这些是高级调节项——除非你正在
为受限主机做调优,否则请保持不设置。
| Variable | Default | Description |
| ----------------------------- | ------- | ----------------------------------------------------------------- |
| `XUI_GOGC` | — | Go GC 目标百分比;值越低 = 占用 RAM 越少,CPU 略增。 |
| `XUI_MEMORY_RELEASE_INTERVAL` | — | 两次 `FreeOSMemory` 调用之间的分钟数;`0` 表示禁用。 |
| `XUI_MEMORY_LIMIT` | — | Go 软内存限制,单位 **MiB**。 |
| `GOMEMLIMIT` | — | Go 语法的软限制(例如 `400MiB`);优先级高于上一项。 |
| `XUI_PPROF` | `false` | 在 `127.0.0.1:6060` 上暴露 pprof 性能分析。 |
## Xray
| Variable | Default | Description |
| ------------------------ | ------- | --------------------- |
| `XRAY_VMESS_AEAD_FORCED` | `false` | 强制启用 VMess AEAD。 |
## 隧道健康监测器
可选的看门狗:它探测一个 URL(可选择**经由**本地 Xray 入站进行),并在反复
失败后重启 Xray。重启会断开所有已连接的客户端,因此请审慎启用。
| Variable | Default | Description |
| ----------------------------- | -------------------------------------------- | ----------------------------------------------------------------- |
| `XUI_TUNNEL_HEALTH_MONITOR` | `false` | 启用监测器。 |
| `XUI_TUNNEL_HEALTH_PROXY` | — | 用于发送探测的代理,例如 `socks5://127.0.0.1:1080`。留空 = 仅检查主机连通性。 |
| `XUI_TUNNEL_HEALTH_URL` | `https://www.cloudflare.com/cdn-cgi/trace` | 要探测的 URL。 |
| `XUI_TUNNEL_HEALTH_INTERVAL` | `30s` | 探测之间的间隔。 |
| `XUI_TUNNEL_HEALTH_TIMEOUT` | `10s` | 单次探测的超时时间。 |
| `XUI_TUNNEL_HEALTH_FAILURES` | `3` | 触发重启前的连续失败次数。 |
| `XUI_TUNNEL_HEALTH_COOLDOWN` | `5m` | 两次重启之间的最小延迟。 |
## 无人值守安装
| Variable | Description |
| -------------------- | -------------------------------------------------------------------------------------------- |
| `XUI_NONINTERACTIVE` | 设为 `1`(或在无 TTY 的环境下运行)即可在零提示的情况下完成安装;生成的凭据会写入 `/etc/x-ui/install-result.env`。参见 [安装](/docs/guide/installation#unattended--cloud-init)。 |
+5
View File
@@ -0,0 +1,5 @@
{
"title": "参考",
"icon": "BookMarked",
"pages": ["env-vars", "database", "ports-firewall", "api"]
}
@@ -0,0 +1,35 @@
---
title: 端口与防火墙
description: 3x-ui 默认使用的端口,以及用于开放这些端口的现成 ufw / nftables 规则。
icon: Network
---
只开放你实际会用到的端口。下面列出了常用端口,并提供了一个用于生成
`ufw` 和 `nftables` 规则的生成器。
## 常用端口
| Port (default) | Purpose |
| -------------- | ----------------------------------------- |
| `22` | SSH(务必保持开放!)。 |
| `2053` | 面板(可配置)。 |
| `2096` | 订阅服务器(如果单独部署)。 |
| `443` | 常用的入站端口(TLS / REALITY)。 |
| `80` / `443` | 反向代理(如果你运行了反向代理)。 |
实际的入站端口取决于你创建的入站配置。
## 生成防火墙规则
<FirewallRulesGenerator />
<Callout type="warn">
在启用默认拒绝策略之前,请始终保持 SSH 处于允许状态,并在另一个会话中进行测试,以免把自己锁在外面。
</Callout>
## 相关内容
<Cards>
<Card title="安全" href="/docs/operations/security" description="Fail2ban、IP 限制与安全加固。" />
<Card title="环境变量" href="/docs/reference/env-vars" description="XUI_PORT 及相关变量。" />
</Cards>