TypeScript SDK
У XLADA нет отдельного опубликованного SDK под именем XLADA. Это не мешает работе: API форка идентичен API Remnawave — те же пути, те же схемы запросов и ответов. Поэтому совместимы типы и контракты Remnawave, а HTTP-клиент собирается за несколько строк.
Установка
Для примеров ниже достаточно стандартного fetch, который есть в Node.js 18+ и
в браузере. Если вам привычнее axios:
npm install axios
Официальный SDK Remnawave — @remnawave/backend-contract — содержит только типы
и zod-схемы, без HTTP-клиента:
npm install @remnawave/backend-contract
В исходниках панели та же библиотека контрактов лежит в
apps/backend/libs/contract (копия для фронтенда — в
apps/frontend/vendor/backend-contract) и называется @xlada/backend-contract.
В npm она не публикуется: подключайте её как локальную зависимость репозитория
("@xlada/backend-contract": "file:./vendor/backend-contract").
Привязывайте версию контракта к версии панели. Контракт и панель развиваются разными циклами, поэтому «последняя» версия типов не всегда описывает именно ваш сервер.
Базовый клиент
Панель ожидает Authorization: Bearer <token>. Если вы обращаетесь к панели
напрямую, из внутренней сети, добавьте заголовки прокси — middleware панели
разрывает соединение без X-Forwarded-For и X-Forwarded-Proto: https.
const PANEL_URL = process.env.XLADA_PANEL_URL ?? 'https://panel.example.com';
const API_TOKEN = process.env.XLADA_API_TOKEN ?? '';
async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
const res = await fetch(`${PANEL_URL}${path}`, {
...init,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${API_TOKEN}`,
'X-Forwarded-For': '127.0.0.1',
'X-Forwarded-Proto': 'https',
...init.headers,
},
});
if (!res.ok) {
throw new Error(`${res.status} ${res.statusText}: ${await res.text()}`);
}
return (await res.json()) as T;
}
Аутентификация
Есть два способа получить токен.
JWT администратора — живёт ограниченное время (JWT_AUTH_LIFETIME, от 12 до
168 часов) и выдаётся методом POST /api/auth/login:
curl -sX POST https://panel.example.com/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"username": "admin", "password": "пароль"}'
Ответ содержит accessToken:
{
"response": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
API-токен — для скриптов и интеграций. Создаётся методом POST /api/tokens
(в интерфейсе — Настройки → API Tokens) и передаётся в том же заголовке
Authorization:
curl -sX POST https://panel.example.com/api/tokens \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name": "ci", "expiresInDays": 365}'
Готовый токен приходит в поле response.token и показывается один раз. Список
доступных областей отдаёт GET /api/tokens/scopes.
Список пользователей
Постраничный вывод: start — смещение, size — размер страницы (от 1 до 1000,
по умолчанию 25).
interface GetUsersResponse {
response: {
users: Array<{
id: number;
username: string;
status: 'ACTIVE' | 'DISABLED' | 'LIMITED' | 'EXPIRED';
shortUuid: string;
expireAt: string;
}>;
total: number;
};
}
const { response } = await api<GetUsersResponse>('/api/users?start=0&size=25');
for (const user of response.users) {
console.log(user.username, user.status, user.expireAt);
}
console.log(`всего: ${response.total}`);
Создание пользователя
POST /api/users принимает username (3–36 символов, только латиница, цифры,
_ и -) и обязательный expireAt в формате ISO 8601.
const created = await api<{ response: { id: number; shortUuid: string } }>(
'/api/users',
{
method: 'POST',
body: JSON.stringify({
username: 'john_doe',
status: 'ACTIVE',
expireAt: '2026-01-17T15:38:45.065Z',
trafficLimitBytes: 0,
trafficLimitStrategy: 'NO_RESET',
}),
},
);
console.log(created.response.shortUuid);
Получение ноды
Одна нода — по её uuid, список — без параметров:
const { response: node } = await api<{
response: { name: string; address: string; port: number | null; isConnected: boolean };
}>(`/api/nodes/${nodeUuid}`);
console.log(node.name, `${node.address}:${node.port}`, node.isConnected);
Где взять типы
Полная спецификация — 162 пути и 29 тегов — лежит на странице
API Specification и в файле static/openapi.json репозитория панели.
Из неё можно сгенерировать .d.ts:
npx openapi-typescript ./openapi.json -o ./src/xlada-api.d.ts
Генерируйте типы из спецификации именно той версии панели, которая у вас развёрнута: между релизами набор полей меняется.
Что дальше
- Go SDK — клиент на стандартной библиотеке Go.
- Python SDK — клиент на
requests. - API Specification — все эндпоинты в OpenAPI.
- Переменные окружения —
JWT_AUTH_LIFETIMEи остальные настройки.