Python SDK
Официального SDK XLADA на Python нет. API XLADA идентичен API Remnawave, поэтому
рабочий клиент пишется на requests за пару десятков строк, а типы берутся из
спецификации OpenAPI.
Для Remnawave существуют community-библиотеки на Python, собранные из той же
спецификации; теоретически они применимы и к XLADA, но официально с XLADA мы их
не проверяли. Пример ниже зависит только от requests.
Установка
python3 -m venv .venv
source .venv/bin/activate
pip install requests
Для асинхронного кода подойдёт httpx, но для скриптов и ботов достаточно
синхронного requests.
Клиент
Токен — JWT от POST /api/auth/login либо API-токен от POST /api/tokens. Оба
передаются в заголовке Authorization: Bearer. Заголовки
X-Forwarded-For и X-Forwarded-Proto: https нужны при прямом обращении к
панели: без них middleware панели разрывает соединение.
import os
import requests
PANEL_URL = os.environ.get("XLADA_PANEL_URL", "https://panel.example.com")
API_TOKEN = os.environ.get("XLADA_API_TOKEN", "")
class XladaClient:
def __init__(self, base_url: str = PANEL_URL, token: str = API_TOKEN) -> None:
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers.update(
{
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"X-Forwarded-For": "127.0.0.1",
"X-Forwarded-Proto": "https",
}
)
def request(self, method: str, path: str, **kwargs) -> dict:
response = self.session.request(method, f"{self.base_url}{path}", timeout=30, **kwargs)
response.raise_for_status()
return response.json()
Аутентификация
Если API-токена нет, получите JWT администратора и передайте его в клиент:
def login(username: str, password: str) -> str:
response = requests.post(
f"{PANEL_URL}/api/auth/login",
json={"username": username, "password": password},
timeout=30,
)
response.raise_for_status()
return response.json()["response"]["accessToken"]
client = XladaClient(token=login("admin", "пароль"))
Долгоживущий API-токен создаётся методом POST /api/tokens — в интерфейсе это
Настройки → API Tokens. Готовый токен показывается один раз, в поле
response.token:
created = client.request("POST", "/api/tokens", json={"name": "bot", "expiresInDays": 365})
print(created["response"]["token"])
Список пользователей
Постраничный вывод: start — смещение, size — размер страницы (1–1000, по
умолчанию 25).
page = client.request("GET", "/api/users", params={"start": 0, "size": 25})
for user in page["response"]["users"]:
print(user["username"], user["status"], user["expireAt"])
print("всего:", page["response"]["total"])
Создание пользователя
POST /api/users принимает username (3–36 символов: латиница, цифры, _, -)
и обязательный expireAt в формате ISO 8601.
created = client.request(
"POST",
"/api/users",
json={
"username": "john_doe",
"status": "ACTIVE",
"expireAt": "2026-01-17T15:38:45.065Z",
"trafficLimitBytes": 0,
"trafficLimitStrategy": "NO_RESET",
},
)
print(created["response"]["shortUuid"])
Получение ноды
Одна нода — по uuid, список нод — GET /api/nodes.
node = client.request("GET", f"/api/nodes/{node_uuid}")["response"]
print(node["name"], node["address"], node["port"], node["isConnected"])
Проверить доступность панели перед работой удобно методом
GET /api/auth/status — он не требует авторизации.
Не храните API-токен в репозитории. Берите его из переменной окружения или
секрета CI, а лишние токены отзывайте через DELETE /api/tokens/{uuid}.
Что дальше
- TypeScript SDK — клиент на
fetchи axios. - Go SDK — клиент на стандартной библиотеке Go.
- API Specification — все 162 эндпоинта в OpenAPI.
- Вебхуки — события панели вместо постоянного опроса.