Перейти к содержимому

Модели и типы API

TypeScript-типы всех сущностей API для быстрой интеграции

Все типы ниже соответствуют реальным ответам REST API панели. Используйте их при написании ботов, SDK и интеграций.

Общие перечисления

TypeScript
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';

Пагинация

Все списковые эндпоинты возвращают обёртку:

TypeScript
interface PaginatedResult<T> {
  items: T[];
  total: number;
  page: number;
  limit: number;
  totalPages: number;
  hasNextPage: boolean;
  hasPreviousPage: boolean;
}

User

Создание — POST /api/users

TypeScript
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

TypeScript
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;
}

Ответ

TypeScript
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

TypeScript
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

TypeScript
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;
}

Ответ

TypeScript
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;
}

Ответ при создании

TypeScript
interface CreateNodeResponse {
  node: NodeResponse;
  secretKey: string;         // base64, передаётся в docker-compose
  dockerCompose: string;     // готовый YAML
}

Host

Создание — POST /api/hosts

TypeScript
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[];
}

Ответ

TypeScript
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

TypeScript
interface CreateSquadRequest {
  name: string;          // 1–255
  sortOrder?: number;
}

Ответ (список)

TypeScript
interface SquadResponse {
  uuid: string;
  name: string;
  sortOrder: number;
  membersCount: number;
  inboundsCount: number;
  createdAt: string;
  updatedAt: string;
}

Детальный ответ — GET /api/squads/:uuid

TypeScript
interface SquadDetailResponse extends SquadResponse {
  inbounds: string[];
  members: string[];
  membersWithUsername: { uuid: string; username: string }[];
  hostExclusions: string[];
}

Управление составом

TypeScript
// 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

TypeScript
interface CreateConfigProfileDto {
  name: string;                        // 1–255
  config: Record<string, unknown>;     // Xray JSON конфиг
}

Ответ

TypeScript
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

TypeScript
interface RegisterDto {
  username: string;   // 3–50, /^[a-zA-Z0-9_-]+$/
  password: string;   // 8–128, обязательны: заглавная, строчная, цифра
}

Вход — POST /api/auth/login

TypeScript
interface LoginDto {
  username: string;
  password: string;
}

Ответ авторизации

TypeScript
interface AuthTokenResponse {
  accessToken: string;       // JWT
  expiresIn: number;         // секунды (604800 = 7 дней)
  role: Role;
  permissions: string[];     // 'users:read', 'nodes:create', ...
}

Текущий пользователь — GET /api/auth/me

TypeScript
interface AuthMeResponse {
  uuid: string;
  username: string;
  role: Role;
  permissions: string[];
}

API Tokens

TypeScript
// 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-кодированными ключами всех протоколов.

Заголовки ответа

TypeScript
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/:idv2ray-links (base64)text/plain
/api/sub/:id/xray-jsonXray JSONapplication/json
/api/sub/:id/clashClash YAMLtext/yaml
/api/sub/:id/singboxSing-box JSONapplication/json
/api/sub/:id/awgAWG configtext/plain
/api/sub/:id/hysteria2Hysteria2 configtext/plain