APILuxe
VPN Billing API — обёртка над Remnawave. Безлимитный трафик, оплата за период и устройства.
Обзор
Все запросы к подпискам идут от клиента с токеном. Операции атомарно списывают баланс и вызывают Remnawave API.
API_URL TOKEN
Аутентификация
Каждый запрос к /subscriptions/* должен содержать заголовок:
X-Token: your_client_token_here
При неверном токене — 401. При отключённом аккаунте — 403.
Rate limit: не более 100 запросов в минуту на токен. При превышении — 429 Too Many Requests.
Endpoints
Возвращает все подписки, созданные через токен клиента. Поле is_active показывает статус в Remnawave.
GET /subscriptions X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
r = requests.get(
f"{API_URL}/subscriptions",
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
async def main():
async with httpx.AsyncClient() as client:
r = await client.get(
f"{API_URL}/subscriptions",
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const r = await fetch(`${API_URL}/subscriptions`, {
headers: { "X-Token": TOKEN }
});
console.log(await r.json());[
{
"uuid": "f47ac10b-...",
"username": "john_doe",
"devices_limit": 5,
"extra_devices": 0,
"extra_devices_cost": 0.0,
"expire_at": "2025-05-23T10:00:00Z",
"is_active": true
}
]
Предварительный расчёт без списания баланса.
Query параметры
| Параметр | Тип | Описание | |
|---|---|---|---|
days | integer | optional | 30, 90, 180 или 360 |
devices | integer | optional | Количество дополнительных устройств |
GET /subscriptions/price?days=90&devices=2 X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
r = requests.get(
f"{API_URL}/subscriptions/price",
params={"days": 90, "devices": 2},
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
async def main():
async with httpx.AsyncClient() as client:
r = await client.get(
f"{API_URL}/subscriptions/price",
params={"days": 90, "devices": 2},
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const r = await fetch(
`${API_URL}/subscriptions/price?days=90&devices=2`,
{ headers: { "X-Token": TOKEN } }
);
console.log(await r.json());{
"days_cost": 400.0,
"devices_cost": 100.0,
"total_cost": 500.0,
"current_balance": 1000.0,
"balance_after": 500.0
}
Создаёт пользователя в Remnawave и списывает баланс. Трафик — безлимитный.
Тело запроса (JSON)
| Поле | Тип | Описание | |
|---|---|---|---|
username | string | required | Имя пользователя (3–50 символов, без пробелов) |
days | integer | required | Только: 30, 90, 180, 360 |
POST /subscriptions/create
X-Token: your_token_here
Content-Type: application/json
{
"username": "john_doe",
"days": 30
}import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
r = requests.post(
f"{API_URL}/subscriptions/create",
json={"username": "john_doe", "days": 30},
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/create",
json={"username": "john_doe", "days": 30},
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const r = await fetch(`${API_URL}/subscriptions/create`, {
method: "POST",
headers: { "X-Token": TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({ username: "john_doe", days: 30 })
});
console.log(await r.json());{
"uuid": "f47ac10b-58cc-...",
"short_uuid": "f47ac10b",
"username": "john_doe",
"subscription_url": "https://...",
"devices_limit": 1,
"connected_devices": 0,
"expire_at": "2025-05-23T10:00:00Z",
"is_active": true
}
Возвращает полную информацию о подписке: дату окончания, количество подключённых устройств, ссылку.
GET /subscriptions/f47ac10b-58cc-... X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.get(
f"{API_URL}/subscriptions/{UUID}",
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.get(
f"{API_URL}/subscriptions/{UUID}",
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}`, {
headers: { "X-Token": TOKEN }
});
console.log(await r.json());{
"uuid": "f47ac10b-58cc-...",
"short_uuid": "f47ac10b",
"username": "john_doe",
"subscription_url": "https://...",
"devices_limit": 5,
"connected_devices": 2,
"extra_devices": 0,
"extra_devices_cost": 0.0,
"expire_at": "2025-05-23T10:00:00Z",
"is_active": true
}
{
"uuid": "f47ac10b-58cc-...",
"short_uuid": "f47ac10b",
"username": "john_doe",
"subscription_url": "https://...",
"devices_limit": 8,
"connected_devices": 6,
"extra_devices": 3,
"extra_devices_cost": 150.0,
"expire_at": "2025-05-23T10:00:00Z",
"is_active": true
}
extra_devices_cost — надбавка к цене продления за докупленные устройства. При продлении итоговая стоимость = цена периода + extra_devices_cost.Увеличивает лимит устройств. Стоимость считается по фиксированной цене за каждое устройство.
Тело запроса
| Поле | Тип | Описание | |
|---|---|---|---|
extra_devices | integer | required | Количество добавляемых устройств (мин. 1) |
POST /subscriptions/f47ac10b-.../add-devices
X-Token: your_token_here
Content-Type: application/json
{
"extra_devices": 2
}import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.post(
f"{API_URL}/subscriptions/{UUID}/add-devices",
json={"extra_devices": 2},
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/{UUID}/add-devices",
json={"extra_devices": 2},
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}/add-devices`, {
method: "POST",
headers: { "X-Token": TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({ extra_devices: 2 })
});
console.log(await r.json());{
"uuid": "f47ac10b-...",
"devices_limit": 3,
"connected_devices": 1,
"expire_at": "2025-05-23T10:00:00Z",
"is_active": true,
// ... остальные поля
}
Продлевает срок подписки от текущей даты окончания (или от сегодня, если уже истекла). Стоимость = цена периода + надбавка за каждое докупленное устройство. В ответе поле charged — фактически списанная сумма.
Тело запроса
| Поле | Тип | Описание | |
|---|---|---|---|
days | integer | required | Только: 30, 90, 180, 360 |
POST /subscriptions/f47ac10b-.../extend
X-Token: your_token_here
Content-Type: application/json
{
"days": 90
}import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.post(
f"{API_URL}/subscriptions/{UUID}/extend",
json={"days": 90},
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/{UUID}/extend",
json={"days": 90},
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}/extend`, {
method: "POST",
headers: { "X-Token": TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({ days: 90 })
});
console.log(await r.json());{
"uuid": "f47ac10b-...",
"expire_at": "2025-08-21T10:00:00Z",
"devices_limit": 5,
"extra_devices": 0,
"extra_devices_cost": 0.0,
"charged": 400.0,
"is_active": true
}
{
"uuid": "f47ac10b-...",
"expire_at": "2025-08-21T10:00:00Z",
"devices_limit": 8,
"extra_devices": 3,
"extra_devices_cost": 150.0,
"charged": 550.0,
"is_active": true
}
charged — итоговая списанная сумма. Равна цене периода плюс extra_devices_cost за каждое докупленное устройство.Очищает список всех подключённых HWID-устройств. Баланс не списывается.
POST /subscriptions/f47ac10b-.../reset-devices X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.post(
f"{API_URL}/subscriptions/{UUID}/reset-devices",
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/{UUID}/reset-devices",
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}/reset-devices`, {
method: "POST",
headers: { "X-Token": TOKEN }
});
console.log(await r.json());{
"uuid": "f47ac10b-...",
"connected_devices": 0,
"devices_limit": 1,
"is_active": true,
// ... остальные поля
}
Убирает одно докупленное устройство (лимит −1). Минимум — 5 устройств. Повторяй запрос столько раз, сколько устройств нужно убрать. Баланс не возвращается.
POST /subscriptions/f47ac10b-.../reset-extra-devices X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.post(
f"{API_URL}/subscriptions/{UUID}/reset-extra-devices",
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/{UUID}/reset-extra-devices",
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}/reset-extra-devices`, {
method: "POST",
headers: { "X-Token": TOKEN }
});
console.log(await r.json());{
"uuid": "f47ac10b-...",
"devices_limit": 7,
"extra_devices": 2,
"extra_devices_cost": 100.0,
"is_active": true
}
{
"error": "no_extra_devices"
}
Убирает 1 дополнительное устройство. Бесплатно, баланс не возвращается. Только если есть докупленные устройства сверх базовых 5.
POST /subscriptions/f47ac10b-.../remove-device X-Token: your_token_here
import requests
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
r = requests.post(
f"{API_URL}/subscriptions/{UUID}/remove-device",
headers={"X-Token": TOKEN}
)
print(r.json())import asyncio
import httpx
API_URL = "https://api.luxenetwork.top"
TOKEN = "your_token_here"
UUID = "f47ac10b-58cc-..."
async def main():
async with httpx.AsyncClient() as client:
r = await client.post(
f"{API_URL}/subscriptions/{UUID}/remove-device",
headers={"X-Token": TOKEN}
)
print(r.json())
asyncio.run(main())const API_URL = "https://api.luxenetwork.top";
const TOKEN = "your_token_here";
const UUID = "f47ac10b-58cc-...";
const r = await fetch(`${API_URL}/subscriptions/${UUID}/remove-device`, {
method: "POST",
headers: { "X-Token": TOKEN }
});
console.log(await r.json());{
"uuid": "f47ac10b-...",
"devices_limit": 6,
"extra_devices": 1,
"extra_devices_cost": 50.0,
// ... остальные поля
}
{
"error": "no_extra_devices",
"message": "Limit is already at default (5)."
}
Коды ошибок
| HTTP | Причина | Пример ответа |
|---|---|---|
401 |
Токен не найден или не передан | {"detail": "Invalid or unknown token"} |
402 |
Недостаточно баланса | {"error":"insufficient_balance","required":400,"available":150,"shortage":250} |
403 |
Клиент отключён | {"detail": "Client account is disabled"} |
422 |
Ошибка валидации (например, days не из списка) | {"detail": [{"msg": "Input should be 30, 90, 180 or 360"}]} |
4xx/5xx |
Ошибка Remnawave API | {"detail": "Remna API 404: ..."} |