Skip to content

API Models & Types

TypeScript types for all API entities — ready for integration

All types below match the actual REST API responses. Use them when building bots, SDKs, and integrations.

Common Enums

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

Pagination

All list endpoints return:

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

User

Create — POST /api/users

TypeScript
interface CreateUserDto {
  username: string;              // 3–50 chars
  trafficLimitBytes?: number;    // >= 0, default 0
  trafficLimitStrategy?: TrafficStrategy; // default 'NO_RESET'
  expireAt?: string | null;      // ISO 8601
  telegramId?: string | null;
  email?: string | null;
  hwidDeviceLimit?: number;      // 0–100, default 0
  description?: string | null;   // max 500
  tag?: string | null;
  squadUuid?: string | null;
}

Update — 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;
}

Response

TypeScript
interface UserResponse {
  uuid: string;
  shortUuid: string;
  username: string;
  status: UserStatus;
  usedTrafficBytes: string;
  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;
}

Detail response — 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;
}

Additional operations

MethodEndpointDescription
POST/api/users/:uuid/disableDisable user
POST/api/users/:uuid/enableEnable user
POST/api/users/:uuid/reset-trafficReset traffic
DELETE/api/users/:uuidDelete user

Node

Create — POST /api/nodes

TypeScript
interface CreateNodeRequest {
  name: string;
  address: string;
  port?: number;                   // default 2222
  protocol?: NodeProtocol;         // default 'XRAY'
  configProfileUuid?: string | null;
  countryCode?: string | null;     // 2-char ISO
  tags?: string[];
  reserveDomain?: string | null;
  priority?: number;               // 0–100
  consumptionMultiplier?: number;   // 0.1–10.0
  awgConfig?: AwgConfig;
  hysteriaConfig?: HysteriaConfig;
}
 
interface AwgConfig {
  listenPort?: number;   // default 51820
  address?: string;      // default '10.8.0.1/24'
  dns?: string;          // default '1.1.1.1, 8.8.8.8'
  mtu?: number;          // default 1420
  jc?: number; jmin?: number; jmax?: number;
  s1?: number; s2?: number;
  h1?: number; h2?: number; h3?: number; h4?: number;
}
 
interface HysteriaConfig {
  listenPort?: number;       // default 443
  obfsType?: string;         // default 'salamander'
  obfsPassword?: string;
  upMbps?: number;           // default 1000
  downMbps?: number;
  masqueradeUrl?: string;
}

Response

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

Create response

TypeScript
interface CreateNodeResponse {
  node: NodeResponse;
  secretKey: string;
  dockerCompose: string;
}

Host

Create — POST /api/hosts

TypeScript
interface CreateHostDto {
  remark: string;
  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[];
}

Response

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

Create — POST /api/squads

TypeScript
interface CreateSquadRequest {
  name: string;
  sortOrder?: number;
}

Response

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

Detail — GET /api/squads/:uuid

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

Membership management

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

Create — POST /api/config-profiles

TypeScript
interface CreateConfigProfileDto {
  name: string;
  config: Record<string, unknown>;     // Xray JSON config
}

Response

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

Register — POST /api/auth/register

TypeScript
interface RegisterDto {
  username: string;   // 3–50, /^[a-zA-Z0-9_-]+$/
  password: string;   // 8–128, requires uppercase, lowercase, digit
}

Login — POST /api/auth/login

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

Token response

TypeScript
interface AuthTokenResponse {
  accessToken: string;
  expiresIn: number;         // seconds (604800 = 7 days)
  role: Role;
  permissions: string[];     // 'users:read', 'nodes:create', ...
}

Current user — 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;          // shown once
  tokenName: string;
  createdAt: string;
}

Use token in header: Authorization: Bearer <token>


Subscription

GET /api/sub/:shortUuid

Returns text/plain with base64-encoded keys for all protocols.

Response headers

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;
  'Support-Url'?: string;
}

Formats

PathFormatContent-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