Модели и типы API
TypeScript-типы всех сущностей API для быстрой интеграции
Все типы ниже соответствуют реальным ответам REST API панели. Используйте их при написании ботов, SDK и интеграций.
Общие перечисления
type UserStatus = 'ACTIVE' | 'DISABLED' | 'LIMITED' | 'EXPIRED';
type TrafficStrategy = 'NO_RESET' | 'DAY' | 'WEEK' | 'MONTH';
type SecurityLayer = 'DEFAULT' | 'TLS' | 'NONE';
type NodeProtocol = 'XRAY' | 'AWG' | 'HYSTERIA2';
type Role = 'SUPER_ADMIN' | 'ADMIN' | 'OPERATOR' | 'VIEWER';Пагинация
Все списковые эндпоинты возвращают обёртку:
interface PaginatedResult<T> {
items: T[];
total: number;
page: number;
limit: number;
totalPages: number;
hasNextPage: boolean;
hasPreviousPage: boolean;
}User
Создание — POST /api/users
interface CreateUserDto {
username: string; // 3–50 символов
trafficLimitBytes?: number; // >= 0, по умолчанию 0
trafficLimitStrategy?: TrafficStrategy; // по умолчанию 'NO_RESET'
expireAt?: string | null; // ISO 8601
telegramId?: string | null;
email?: string | null;
hwidDeviceLimit?: number; // 0–100, по умолчанию 0
description?: string | null; // до 500 символов
tag?: string | null;
squadUuid?: string | null;
}Обновление — PUT /api/users/:uuid
interface UpdateUserDto {
username?: string;
status?: UserStatus;
trafficLimitBytes?: number | null;
trafficLimitStrategy?: TrafficStrategy;
expireAt?: string | null;
telegramId?: string | null;
email?: string | null;
hwidDeviceLimit?: number;
description?: string | null;
tag?: string | null;
squadUuid?: string | null;
}Ответ
interface UserResponse {
uuid: string;
shortUuid: string;
username: string;
status: UserStatus;
usedTrafficBytes: string; // BigInt как строка
trafficLimitBytes: string;
trafficLimitStrategy: TrafficStrategy;
expireAt: string | null;
telegramId: string | null;
email: string | null;
hwidDeviceLimit: number;
description: string | null;
tag: string | null;
onlineAt: string | null;
createdAt: string;
updatedAt: string;
}Детальный ответ — GET /api/users/:uuid
interface UserDetailResponse extends UserResponse {
squad: { uuid: string; name: string } | null;
devices: UserHwidDeviceDto[];
awgKey: {
publicKey: string;
assignedIp: string;
createdAt: string;
} | null;
hysteriaPassword: {
createdAt: string;
} | null;
}
interface UserHwidDeviceDto {
uuid: string;
deviceId: string;
platform: string | null;
userAgent: string | null;
firstSeenAt: string;
lastSeenAt: string;
}Дополнительные операции
| Метод | Эндпоинт | Описание |
|---|---|---|
POST | /api/users/:uuid/disable | Заблокировать |
POST | /api/users/:uuid/enable | Разблокировать |
POST | /api/users/:uuid/reset-traffic | Сбросить трафик |
DELETE | /api/users/:uuid | Удалить |
Node
Создание — POST /api/nodes
interface CreateNodeRequest {
name: string; // 1–100
address: string; // IP или домен
port?: number; // по умолчанию 2222
protocol?: NodeProtocol; // по умолчанию 'XRAY'
configProfileUuid?: string | null;
countryCode?: string | null; // 2 символа (RU, NL, DE...)
tags?: string[];
reserveDomain?: string | null;
priority?: number; // 0–100
consumptionMultiplier?: number; // 0.1–10.0
awgConfig?: AwgConfig;
hysteriaConfig?: HysteriaConfig;
}
interface AwgConfig {
listenPort?: number; // по умолчанию 51820
address?: string; // по умолчанию '10.8.0.1/24'
dns?: string; // по умолчанию '1.1.1.1, 8.8.8.8'
mtu?: number; // по умолчанию 1420
jc?: number; jmin?: number; jmax?: number;
s1?: number; s2?: number;
h1?: number; h2?: number; h3?: number; h4?: number;
}
interface HysteriaConfig {
listenPort?: number; // по умолчанию 443
obfsType?: string; // по умолчанию 'salamander'
obfsPassword?: string;
upMbps?: number; // по умолчанию 1000
downMbps?: number;
masqueradeUrl?: string;
}Ответ
interface NodeResponse {
uuid: string;
name: string;
address: string;
port: number;
protocol: NodeProtocol;
isConnected: boolean;
isDisabled: boolean;
xrayVersion: string | null;
nodeVersion: string | null;
usersOnline: number;
trafficLimitBytes: string;
trafficUsedBytes: string;
configProfileUuid: string | null;
countryCode: string | null;
tags: string[];
reserveDomain: string | null;
maxOnline: number;
priority: number;
excludeFromBalancing: boolean;
consumptionMultiplier: number;
maxBandwidthMbps: number | null;
certificateInfo?: CertificateInfo;
latencyMs?: number | null;
uptimeSeconds?: number | null;
createdAt: string;
updatedAt: string;
}
interface CertificateInfo {
status: 'valid' | 'expiring_soon' | 'expired' | 'missing';
expiresAt: string | null;
daysUntilExpiry: number | null;
subject: string | null;
}Ответ при создании
interface CreateNodeResponse {
node: NodeResponse;
secretKey: string; // base64, передаётся в docker-compose
dockerCompose: string; // готовый YAML
}Host
Создание — POST /api/hosts
interface CreateHostDto {
remark: string; // 1–255
address: string;
port: number; // 1–65535
sni?: string | null;
sniFromAddress?: boolean;
host?: string | null;
fingerprint?: string | null;
path?: string | null;
securityLayer?: SecurityLayer;
useNodeAddress?: boolean;
configProfileUuid: string;
configProfileInboundUuid: string;
announceUrl?: string | null;
nodeUuids?: string[];
}Ответ
interface HostResponse {
uuid: string;
remark: string;
address: string;
port: number;
sni: string | null;
sniFromAddress: boolean;
host: string | null;
fingerprint: string | null;
path: string | null;
securityLayer: SecurityLayer;
useNodeAddress: boolean;
configProfileUuid: string;
configProfileInboundUuid: string;
isDisabled: boolean;
sortOrder: number;
announceUrl: string | null;
realityPublicKey?: string;
addresses: HostAddressSummary[];
nodes: { uuid: string; name: string; countryCode: string | null }[];
configProfileInbound: {
uuid: string;
tag: string;
type: string;
network: string;
security: string;
port: number;
} | null;
createdAt: string;
updatedAt: string;
}
interface HostAddressSummary {
uuid: string;
address: string;
port: number | null;
weight: number;
isEnabled: boolean;
remark: string | null;
}Squad
Создание — POST /api/squads
interface CreateSquadRequest {
name: string; // 1–255
sortOrder?: number;
}Ответ (список)
interface SquadResponse {
uuid: string;
name: string;
sortOrder: number;
membersCount: number;
inboundsCount: number;
createdAt: string;
updatedAt: string;
}Детальный ответ — GET /api/squads/:uuid
interface SquadDetailResponse extends SquadResponse {
inbounds: string[];
members: string[];
membersWithUsername: { uuid: string; username: string }[];
hostExclusions: string[];
}Управление составом
// PUT /api/squads/:uuid/inbounds
interface SetSquadInboundsRequest { inboundUuids: string[]; }
// POST /api/squads/:uuid/members
interface AddSquadMembersRequest { userUuids: string[]; }
// DELETE /api/squads/:uuid/members
interface RemoveSquadMembersRequest { userUuids: string[]; }Config Profile
Создание — POST /api/config-profiles
interface CreateConfigProfileDto {
name: string; // 1–255
config: Record<string, unknown>; // Xray JSON конфиг
}Ответ
interface ConfigProfileResponse {
uuid: string;
name: string;
config: Record<string, unknown>;
inbounds: ConfigProfileInbound[];
createdAt: string;
updatedAt: string;
}
interface ConfigProfileInbound {
uuid: string;
tag: string;
type: string; // 'vless', 'vmess', 'trojan', 'awg', 'hysteria2'
network: string; // 'tcp', 'udp', 'ws', 'grpc'
security: string; // 'reality', 'tls', 'none'
port: number;
}Auth
Регистрация — POST /api/auth/register
interface RegisterDto {
username: string; // 3–50, /^[a-zA-Z0-9_-]+$/
password: string; // 8–128, обязательны: заглавная, строчная, цифра
}Вход — POST /api/auth/login
interface LoginDto {
username: string;
password: string;
}Ответ авторизации
interface AuthTokenResponse {
accessToken: string; // JWT
expiresIn: number; // секунды (604800 = 7 дней)
role: Role;
permissions: string[]; // 'users:read', 'nodes:create', ...
}Текущий пользователь — GET /api/auth/me
interface AuthMeResponse {
uuid: string;
username: string;
role: Role;
permissions: string[];
}API Tokens
// POST /api/api-tokens
interface CreateApiTokenDto { tokenName: string; }
interface CreatedApiToken {
uuid: string;
token: string; // показывается один раз
tokenName: string;
createdAt: string;
}Токен передаётся в заголовке: Authorization: Bearer <token>
Подписка
GET /api/sub/:shortUuid
Возвращает text/plain с base64-кодированными ключами всех протоколов.
Заголовки ответа
interface SubscriptionHeaders {
'Subscription-Userinfo': string; // "upload=0; download=X; total=Y; expire=Z"
'x-user-uuid': string;
'Profile-Update-Interval'?: string;
'Profile-Title'?: string; // base64
'Support-Url'?: string;
}Форматы
| Путь | Формат | Content-Type |
|---|---|---|
/api/sub/:id | v2ray-links (base64) | text/plain |
/api/sub/:id/xray-json | Xray JSON | application/json |
/api/sub/:id/clash | Clash YAML | text/yaml |
/api/sub/:id/singbox | Sing-box JSON | application/json |
/api/sub/:id/awg | AWG config | text/plain |
/api/sub/:id/hysteria2 | Hysteria2 config | text/plain |