Files
3x-ui/docs/content/docs/en/reference/api/inbounds.mdx
T
MHSanaei 823db05966 fix(inbounds): keep the stored client list and enable on inbound save
Invariant: saving an inbound's configuration never changes which clients it
holds nor whether it is enabled; both have their own endpoints. The edit
modal posts back the clients and the enable flag it loaded when it opened.
A client added meanwhile (another admin, the bot, the API, LDAP) was
detached and its stats deleted; a client deleted meanwhile came back with
its credentials, restoring access that had been revoked; an inbound
switched off meanwhile was switched back on.

For every save but a master's node-sync push, UpdateInbound now takes the
client list and enable from the row it re-reads inside the writer; this
replaces the lifecycle-only carry from the previous commit. Client
validation (renewal schedule, Hysteria auth, TUIC credentials) moves after
that swap so it judges the clients actually saved: a protocol switch keeps
the stored clients, and #6268's refusal must apply to them.

The edit form no longer loads or sends clients, so neither the JSON editor
nor validation sees a copy the server ignores, and the enable switch shows
only when adding; the list toggle (/setEnable) covers existing inbounds.

Tests that added or re-keyed clients through a panel inbound save pinned
the old rule; they now drive the master-push path, where payload clients
still apply.
2026-09-28 13:23:48 +02:00

209 lines
19 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Inbounds
description: Manage inbound configurations and their clients. All endpoints live
under /panel/api/inbounds and require a logged-in session or Bearer token.
Link-generating endpoints honour forwarded headers only when the request comes
from a configured trusted proxy.
full: true
_openapi:
preload:
- ./public/openapi.json
toc:
- depth: 2
title: List every inbound owned by the authenticated user, including each
inbound’s 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.
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: Same shape as /list but with settings.clients[] stripped down to {email,
enable, comment} and ClientStats not enriched with UUID/SubId. Use this
for list pages; fetch /get/:id when you need the full per-client payload
(uuid, password, flow, ...).
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: Lightweight picker projection of the authenticated user’s 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.
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: Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, mtproto) across all inbounds and all of their clients.
Links are rendered through the subscription engine, so the configured
remark template (name-only display part) is applied per client — the
same output the client info/QR pages use. Protocols without a URL form
(socks, http, mixed, wireguard, dokodemo, tunnel) contribute nothing.
Used by the panel’s "Export all inbound links" action.
url: '#return-every-protocol-url-vless-vmess-trojan-ss-hysteria-mtproto-across-all-inbounds-and-all-of-their-clients-links-are-rendered-through-the-subscription-engine-so-the-configured-remark-template-name-only-display-part-is-applied-per-client--the-same-output-the-client-infoqr-pages-use-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing-used-by-the-panels-export-all-inbound-links-action'
- depth: 2
title: Fetch a single inbound by numeric ID.
url: '#fetch-a-single-inbound-by-numeric-id'
- depth: 2
title: 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).
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: Delete an inbound by ID. Also removes its associated client stats rows.
url: '#delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows'
- depth: 2
title: 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.
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: 'Replace an inbound’s configuration. Body shape mirrors /add, but the
inbound keeps its stored client list and enable flag: settings.clients
and enable in the body are ignored. Manage clients through the
/panel/api/clients endpoints and toggle the inbound with /setEnable.'
url: '#replace-an-inbounds-configuration-body-shape-mirrors-add-but-the-inbound-keeps-its-stored-client-list-and-enable-flag-settingsclients-and-enable-in-the-body-are-ignored-manage-clients-through-the-panelapiclients-endpoints-and-toggle-the-inbound-with-setenable'
- depth: 2
title: Toggle only the enable flag without serialising the whole settings JSON.
Recommended for UI switches on large inbounds.
url: '#toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds'
- depth: 2
title: Set only the subscription sort order. Reads the stored inbound, so a
reorder cannot carry a stale client list over a concurrent edit.
url: '#set-only-the-subscription-sort-order-reads-the-stored-inbound-so-a-reorder-cannot-carry-a-stale-client-list-over-a-concurrent-edit'
- depth: 2
title: Zero out upload + download counters for a single inbound. Does not touch
per-client counters.
url: '#zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters'
- depth: 2
title: Remove every client attached to a single inbound while keeping the
inbound itself. Collects emails from settings.clients[] and feeds them
into the optimized bulk-delete path (runtime user removal + traffic-row
cleanup + SyncInbound). Destructive and cannot be undone.
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: Reset upload + download counters on every inbound. Destructive —
accounting history is lost.
url: '#reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost'
- depth: 2
title: Bulk-import an inbound from a JSON blob (e.g. one exported via the UI).
The body uses form encoding with a single "data" field.
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: Receive a master panel's aggregated per-client usage, keyed by the
master's 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.
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: List the fallback rules attached to a master VLESS/Trojan TCP-TLS
inbound. Each rule links one child inbound (the dest) to optional
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
inbound's listen+port is used.
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: Replace the entire fallback list for a master inbound. Body is JSON.
Triggers an Xray restart.
url: '#replace-the-entire-fallback-list-for-a-master-inbound-body-is-json-triggers-an-xray-restart'
structuredData:
headings:
- content: List every inbound owned by the authenticated user, including each
inbound’s 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.
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: Same shape as /list but with settings.clients[] stripped down to
{email, enable, comment} and ClientStats not enriched with UUID/SubId.
Use this for list pages; fetch /get/:id when you need the full
per-client payload (uuid, password, flow, ...).
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: Lightweight picker projection of the authenticated user’s 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.
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: Return every protocol URL (vless://, vmess://, trojan://, ss://,
hysteria://, mtproto) across all inbounds and all of their clients.
Links are rendered through the subscription engine, so the configured
remark template (name-only display part) is applied per client — the
same output the client info/QR pages use. Protocols without a URL form
(socks, http, mixed, wireguard, dokodemo, tunnel) contribute nothing.
Used by the panel’s "Export all inbound links" action.
id: return-every-protocol-url-vless-vmess-trojan-ss-hysteria-mtproto-across-all-inbounds-and-all-of-their-clients-links-are-rendered-through-the-subscription-engine-so-the-configured-remark-template-name-only-display-part-is-applied-per-client--the-same-output-the-client-infoqr-pages-use-protocols-without-a-url-form-socks-http-mixed-wireguard-dokodemo-tunnel-contribute-nothing-used-by-the-panels-export-all-inbound-links-action
- content: Fetch a single inbound by numeric ID.
id: fetch-a-single-inbound-by-numeric-id
- content: 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).
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: Delete an inbound by ID. Also removes its associated client stats rows.
id: delete-an-inbound-by-id-also-removes-its-associated-client-stats-rows
- content: 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.
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: 'Replace an inbound’s configuration. Body shape mirrors /add, but the
inbound keeps its stored client list and enable flag: settings.clients
and enable in the body are ignored. Manage clients through the
/panel/api/clients endpoints and toggle the inbound with /setEnable.'
id: replace-an-inbounds-configuration-body-shape-mirrors-add-but-the-inbound-keeps-its-stored-client-list-and-enable-flag-settingsclients-and-enable-in-the-body-are-ignored-manage-clients-through-the-panelapiclients-endpoints-and-toggle-the-inbound-with-setenable
- content: Toggle only the enable flag without serialising the whole settings
JSON. Recommended for UI switches on large inbounds.
id: toggle-only-the-enable-flag-without-serialising-the-whole-settings-json-recommended-for-ui-switches-on-large-inbounds
- content: Set only the subscription sort order. Reads the stored inbound, so a
reorder cannot carry a stale client list over a concurrent edit.
id: set-only-the-subscription-sort-order-reads-the-stored-inbound-so-a-reorder-cannot-carry-a-stale-client-list-over-a-concurrent-edit
- content: Zero out upload + download counters for a single inbound. Does not
touch per-client counters.
id: zero-out-upload--download-counters-for-a-single-inbound-does-not-touch-per-client-counters
- content: Remove every client attached to a single inbound while keeping the
inbound itself. Collects emails from settings.clients[] and feeds them
into the optimized bulk-delete path (runtime user removal +
traffic-row cleanup + SyncInbound). Destructive and cannot be undone.
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: Reset upload + download counters on every inbound. Destructive —
accounting history is lost.
id: reset-upload--download-counters-on-every-inbound-destructive--accounting-history-is-lost
- content: Bulk-import an inbound from a JSON blob (e.g. one exported via the UI).
The body uses form encoding with a single "data" field.
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: Receive a master panel's aggregated per-client usage, keyed by the
master's 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.
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: List the fallback rules attached to a master VLESS/Trojan TCP-TLS
inbound. Each rule links one child inbound (the dest) to optional
SNI/ALPN/path/dest/xver match criteria. When dest is empty the child
inbound's listen+port is used.
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: Replace the entire fallback list for a master inbound. Body is JSON.
Triggers an Xray restart.
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/allLinks","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}/subSortIndex","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 />
</>
);
}