Remnawave Panel v3.0.0

[!tip] Важно
Перед обновлением, обязательно сделать полный бекап ваших данных (база данных, .env-файл). См. Инструменты бекапа и восстановления.

На что обратить внимание?

Это мажорный релиз с серьезными изменениями API. Самое главное: пользователи больше не идентифицируются по UUID – везде используется числовой id. Кроме того, приведены в порядок коды ответов, все ошибки (400, 404, 500) типизированы и задокументированы в OpenAPI-спецификации. Если вы используете API напрямую или через сгенерированный SDK – обязательно прочитайте разделы ниже.


Новые .env переменные

// error-start
JWT_AUTH_SECRET=значение_1
// error-end


// success-start
APP_SECRET=значение_1
// success-end

Переименуйте переменную JWT_AUTH_SECRET на APP_SECRET (содержимое оставьте прежним!).

Следующие переменные можно удалить:

JWT_API_TOKENS_SECRET=change_me
SWAGGER_PATH=/docs
SCALAR_PATH=/scalar
IS_DOCS_ENABLED=true

Документация и инструменты теперь всегда доступны по фиксированным путям:

  • Swagger – /api/backend-tools/swagger
  • Scalar – /api/backend-tools/scalar
  • Bull Board (очереди) – /api/backend-tools/queues

Всё, что находится под /api/backend-tools, защищено новой авторизацией. В панели для этого появилась карточка Backend Tools (раздел Remnawave Settings) с кнопкой входа в один клик.

Настройки подписки переехали в Response Headers

Из настроек подписки удалены поля profileTitle, profileUpdateInterval, supportLink, isProfileWebpageUrlEnabled, happAnnounce, happRouting (и соответствующие карточки в UI). Их значения автоматически мигрируют в обычные кастомные заголовки ответа (хедеры): profile-title, profile-update-interval, support-url, profile-web-page-url, announce, routing.

Обратите внимание на изменение поведения: раньше заголовок routing отправлялся только клиентам Happ, теперь настроенные заголовки отправляются всем клиентам без фильтра по User-Agent. Значения заголовков поддерживают Template Variables и префикс rwEncodeBase64: (кодирует значение и отдаёт его как base64:<...>).

У внешних сквадов поле responseHeaders разделено на responseHeadersAdd (добавить заголовки) и responseHeadersRemove (список заголовков, которые нужно вырезать из ответа). Существующие значения мигрируют автоматически.


Пользователи теперь идентифицируются числовым id, поле uuid удалено

Поле uuid полностью удалено из объекта пользователя во всех ответах API. Единственный идентификатор пользователя теперь – числовой id. Все пути с {uuid} пользователя переехали на {userId}:

Было Стало
DELETE /api/users/{uuid} DELETE /api/users/{userId}
GET /api/bandwidth-stats/users/{uuid} GET /api/bandwidth-stats/users/{userId}
GET /api/hwid/devices/{userUuid} GET /api/hwid/devices/{userId}
GET /api/subscriptions/by-uuid/{uuid} GET /api/subscriptions/by-id/{userId}
GET /api/subscriptions/connection-keys/{uuid} GET /api/subscriptions/connection-keys/{userId}
GET /api/users/{uuid}/accessible-nodes GET /api/users/{userId}/accessible-nodes
GET /api/users/{uuid}/subscription-request-history GET /api/users/{userId}/subscription-request-history
GET /api/users/{uuid} GET /api/users/{userId}
GET/PUT /api/metadata/user/{uuid} GET/PUT /api/metadata/user/{userId}
POST /api/users/{uuid}/actions/* POST /api/users/{userId}/actions/*

Тела запросов изменились соответственно:

  • все bulk-операции над пользователями (/api/users/bulk/*) принимают userIds (массив чисел) вместо uuids;
  • HWID-эндпоинты (/api/hwid/devices*) принимают userId вместо userUuid;
  • PATCH /api/users идентифицирует пользователя по id вместо uuid;
  • POST /api/users больше не принимает свой uuid при создании;
  • POST /api/users/resolve – поле uuid удалено (используйте id, shortUuid или username).

Поиск по username и shortUuid (/api/users/by-username/{username},/api/users/by-short-uuid/{shortUuid}) не изменился. Если вы где-то храните UUID пользователей – мигрируйте на числовые id до обновления интеграций.

Удалены эндпоинты поиска пользователей по Telegram ID, email, тегу и ID

Следующие эндпоинты удалены:

  • GET /api/users/by-telegram-id/{telegramId}
  • GET /api/users/by-email/{email}
  • GET /api/users/by-tag/{tag}
  • GET /api/users/by-id/{id} (теперь это просто GET /api/users/{userId})

Вместо них используйте GET /api/users/stream – эндпоинт получил новые query-параметры фильтрации: telegramId, email, tag, а также status, trafficLimitStrategy и externalSquadUuid.

Пример – получить пользователей по Telegram ID: GET /api/users/stream?telegramId=123456789

Эндпоинт использует курсорную пагинацию: передавайте nextCursor из предыдущего ответа в параметре cursor, пока не получите все записи (size – до 1000 записей за запрос, по умолчанию 250).

Новый эндпоинт: продление подписки одного пользователя

POST /api/users/{userId}/actions/extend с телом { "days": N } продлевает срок действия:

  • если пользователь EXPIRED – новая дата считается от текущего момента, и пользователь становится ACTIVE;
  • если пользователь ACTIVE – дни добавляются к текущей дате истечения.

Новые эндпоинты статистики

  • GET /api/system/stats/digest – агрегированная сводка за период: созданные и истёкшие пользователи, общий трафик, трафик пользователей, созданных за период, новые HWID-устройства;
  • GET /api/system/stats/http – счётчики HTTP-запросов по роутам;
  • POST /api/bandwidth-stats/nodes/usage – пользователи, потратившие на указанных нодах больше minTotalBytes за период;
  • GET /api/internal-squads/{uuid}/usage – потребление трафика пользователями сквада.
  • GET /api/bandwidth-stats/internal-squads/{squadUuid}/users/{userId}/usage – дневное потребление одного пользователя на нодах сквада.

Legacy-эндпоинты статистики (.../users/{uuid}/legacy, .../nodes/{uuid}/users/legacy) удалены.

Также у внутренних сквадов появились операции над списком пользователей: POST .../bulk-actions/add-many-users и DELETE .../bulk-actions/remove-many-users (тело userIds, до 1000 за запрос, выполняются в фоне, 202).

DELETE-запросы теперь возвращают 204 (или 202) без тела ответа

Раньше все DELETE-эндпоинты возвращали 200 с телом вида { "response": { "isDeleted": true } }. Теперь:

  • 204 No Content – операция выполнена, тело ответа отсутствует (удаление пользователя, ноды, хоста, токена и т.д.);
  • 202 Accepted – операция принята и выполняется в фоне (например, удаление пользователей из сквада).

Массовые (bulk) операции теперь возвращают 202 или 204 без тела

Bulk-операции над пользователями и нодами (/api/users/bulk/*, /api/nodes/bulk-actions, /api/hosts/bulk/*, добавление/удаление пользователей в сквадах, рестарт нод) больше не возвращают { "affectedRows": N } :

  • 202 Accepted – операция поставлена в очередь и выполняется в фоне;
  • 204 No Content – операция выполнена, тело не возвращается.

Число затронутых записей из ответа узнать больше нельзя – учитывайте это в интеграциях.

Типизированные ошибки 400, 404 и 500

Все эндпоинты теперь документируют ошибки едиными схемами:

  • 400RemnawaveBadRequestErrorDto (бизнес-ошибки, с полями timestamp, path, message, errorCode) или RemnawaveValidationErrorDto (ошибки валидации, с полями message, statusCode, errors[]);
  • 404RemnawaveNotFoundErrorDto;
  • 500RemnawaveInternalServerErrorDto.

Все возможные значения message и errorCode перечислены в спецификации per-endpoint.

GET /api/keygen: pubKey заменён на secretKey

В ответе эндпоинта поле response.pubKey заменено на response.secretKey.

Переименован модуль IP: /api/ip-control/api/connections

Эндпоинты переехали на новые пути и получили единообразную структуру:

Было Стало
POST /api/ip-control/fetch-ips/{uuid} POST /api/connections/by-user/{userId}
GET /api/ip-control/fetch-ips/result/{jobId} GET /api/connections/by-user/{jobId}
POST /api/ip-control/fetch-users-ips/{nodeUuid} POST /api/connections/by-node/{nodeUuid
GET /api/ip-control/fetch-users-ips/result/{jobId} GET /api/connections/by-node/{jobId}
POST /api/ip-control/drop-connections POST /api/connections/drop

Логика не изменилась: POST запускает фоновую задачу и возвращает jobId, GET с этим jobId отдаёт результат. Старые пути удалены. Обратите внимание: by-user теперь принимает числовой userId, а в теле POST /api/connections/drop поле userUuids заменено на userIds.

Скоупы API-токенов мигрируют автоматически. Ресурс ip-control переименован в connections (ip-control:fetch-ipsconnections:by-user, ip-control:drop-connectionsconnections:drop и т.д.). Скоупы существующих токенов будут обновлены при апдейте панели автоматически – ничего делать не нужно. Но если ваша интеграция сама создаёт токены с этими скоупами, обновите строки на новые.

Внешние сквады: responseHeaders разделён на add/remove

В настройках внешних сквадов поле responseHeaders заменено на два: responseHeadersAdd (объект «заголовок → значение») и responseHeadersRemove (массив имён заголовков). Это касается тела PATCH /api/external-squads и объектов сквадов во всех ответах.

Из настроек подписки удалены некоторые поля

Из GET/PATCH /api/subscription-settings удалены поля profileTitle, profileUpdateInterval, supportLink, isProfileWebpageUrlEnabled, happAnnounce, happRouting – эти настройки теперь управляются через “Кастомные хедеры”.

Также из ответа GET /api/tokens удалён объект docs.


Бекенд

Новый функционал

  • Экспорт событий в Redis Streams
    Опциональный экспорт данных панели во внешние системы. Включается EXPORT_TO_STREAM_ENABLED=true, длина стримов ограничивается EXPORT_TO_STREAM_MAXLEN (по умолчанию 3000).
    Три стрима: ioraw:export:user_usage (данные трафика пользователей по нодам), ioraw:export:subscription_requests (запросы подписки; работает даже при SERVICE_DISABLE_SRH_RECORDS=true), ioraw:export:node_connections (снапшот онлайн-пользователей и их IP по нодам каждые 5 минут, хранится 1 час). Схемы сообщений опубликованы в @remnawave/backend-contract и в OpenAPI.
  • Сводная статистика за период (digest)
    GET /api/system/stats/digest – созданные и истёкшие пользователи, общий трафик, трафик пользователей, созданных за период, и новые HWID-устройства за диапазон start, end.
  • Raw-хост в кастомных примечаниях
    Custom remark (в настройках подписки и внешних сквадах) может быть JSON-объектом – он валидируется по схеме хоста из raw-формата подписки и вставляется в подписку как «сырой» хост.
  • Дополнительные вебхук-URL для отдельных событий
  • В notifications-config.yml у события можно указать additionalWebhookUrls: [...] – эти URL добавляются к глобальному WEBHOOK_URL только для конкретного события.

Исправления

  • Mihomo: Hysteria2 obfs Gecko (#194)
  • Shadowsocks 2022: валидация ключа (#193)
  • Fallback-хосты в raw-подписке
  • Запрет пустых outbounds
    Валидатор Xray-конфига теперь отклоняет конфиг без outbounds.
  • …прочие изменения

Улучшения

  • Zod v4
  • Лимиты уведомлений расширены до 31 дня
    EXPIRATION_NOTIFICATIONS теперь принимает значения от −744 до 744 часов (было ±168), NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS – до 744.
API Changelog 2.8.1 vs. 3.0.0

Users are now addressed by numeric id — user uuid removed

The user entity is now identified exclusively by its numeric id. The uuid property was removed from every user object in responses (users, users stream, subscriptions, resolve, etc.), and all user-scoped routes changed their path parameter from {uuid} to {userId} (type number). The telegramId property type changed from integer to number.

Renamed paths:

  • GET /api/users/{uuid}GET /api/users/{userId}
  • DELETE /api/users/{uuid}DELETE /api/users/{userId}
  • GET /api/users/{uuid}/accessible-nodesGET /api/users/{userId}/accessible-nodes
  • GET /api/users/{uuid}/subscription-request-historyGET /api/users/{userId}/subscription-request-history
  • POST /api/users/{uuid}/actions/disablePOST /api/users/{userId}/actions/disable
  • POST /api/users/{uuid}/actions/enablePOST /api/users/{userId}/actions/enable
  • POST /api/users/{uuid}/actions/reset-trafficPOST /api/users/{userId}/actions/reset-traffic
  • POST /api/users/{uuid}/actions/revokePOST /api/users/{userId}/actions/revoke
  • GET /api/hwid/devices/{userUuid}GET /api/hwid/devices/{userId}
  • GET /api/metadata/user/{uuid}GET /api/metadata/user/{userId}
  • PUT /api/metadata/user/{uuid}PUT /api/metadata/user/{userId}
  • GET /api/subscriptions/by-uuid/{uuid}GET /api/subscriptions/by-id/{userId}
  • GET /api/subscriptions/connection-keys/{uuid}GET /api/subscriptions/connection-keys/{userId}
  • GET /api/bandwidth-stats/users/{uuid}GET /api/bandwidth-stats/users/{userId}

GET /api/users/by-id/{id} was removed — GET /api/users/{userId} is now the lookup by id. Lookups by username and shortUuid (/api/users/by-username/{username}, /api/users/by-short-uuid/{shortUuid}) are unchanged.

Request bodies changed accordingly:

  • All user bulk operations take userIds (array of numbers) instead of uuids: POST /api/users/bulk/delete, bulk/update, bulk/reset-traffic, bulk/revoke-subscription, bulk/extend-expiration-date, bulk/update-squads.
  • HWID device bodies take userId instead of userUuid: POST /api/hwid/devices, POST /api/hwid/devices/delete, POST /api/hwid/devices/delete-all.
  • PATCH /api/users identifies the user by id instead of uuid.
  • POST /api/users no longer accepts a custom uuid.
  • POST /api/users/resolve no longer accepts uuid (use id, shortUuid or username).
  • POST /api/connections/drop (former drop-connections): dropBy.userUuidsdropBy.userIds.

Response bodies: GET /api/hwid/devices/top-users dropped userUuid (use id), GET /api/node-plugins/torrent-blocker/stats topUsers\[\].uuidtopUsers\[\].userId, and the user object in subscription responses no longer contains uuid.


Removed user lookup endpoints

The following endpoints were removed. Use GET /api/users/stream with the new filter parameters (or GET /api/users/{userId} for the id lookup) instead.

  • GET /api/users/by-email/{email}
  • GET /api/users/by-tag/{tag}
  • GET /api/users/by-telegram-id/{telegramId}
  • GET /api/users/by-id/{id}

Users stream: new filter parameters

GET /api/users/stream gains new optional query parameters: telegramId, email, tag, status, trafficLimitStrategy and externalSquadUuid. The cursor parameter type changed from string to number, and size now has a default of 250 (min 1, max 1000).

Affected endpoints:

  • GET /api/users/stream

New endpoint: extend a single user's expiration date

POST /api/users/{userId}/actions/extend with body { "days": N } (min 1). If the user is EXPIRED, the new expiration date is calculated from the current date and the user becomes ACTIVE; if the user is ACTIVE, the days are added to the existing expiration date. Returns 200 with the updated user object.

Affected endpoints:

  • POST /api/users/{userId}/actions/extend (new)

Internal squads: targeted bulk membership operations

New endpoints to add or remove a specific list of users in an internal squad (body: userIds, 1–1000 items). Both are processed in the background and return 202 with no body. The existing add-users/remove-users endpoints (which affect all users) are unchanged in semantics.

Affected endpoints:

  • POST /api/internal-squads/{uuid}/bulk-actions/add-many-users (new)
  • DELETE /api/internal-squads/{uuid}/bulk-actions/remove-many-users (new)

Bandwidth stats: new usage endpoints, legacy endpoints removed

New endpoints:

  • POST /api/bandwidth-stats/nodes/usage — users whose total usage on the given nodes (body: nodesUuids) over the period is ≥ minTotalBytes (query: start, end, minTotalBytes).
  • GET /api/internal-squads/{uuid}/usage and GET /api/bandwidth-stats/internal-squads/{uuid}/usage — per-user traffic usage scoped to the nodes reachable via the internal squad inbounds, cursor-paginated (limit default 250, cursor, minTotalBytes).
  • GET /api/bandwidth-stats/internal-squads/{squadUuid}/users/{userId}/usage — daily (zero-filled) usage of a single user on the internal squad nodes for a period.

Removed endpoints:

  • GET /api/bandwidth-stats/users/{uuid}/legacy
  • GET /api/bandwidth-stats/nodes/{uuid}/users/legacy

The topNodesLimit/topUsersLimit query parameters on the remaining bandwidth-stats endpoints are now optional with defaults (20/100, min 1).


New system stats endpoints

  • GET /api/system/stats/digest — aggregated statistics for a datetime range \[start, end): created/expired user counts, total traffic, traffic spent by users created within the range, and new HWID devices.
  • GET /api/system/stats/http — HTTP request counters per route (method, route, count) and a total.

GET /api/system/stats/bandwidth gains an optional tz query parameter.


DELETE endpoints now return 204 No Content

All DELETE endpoints previously returned 200 with a JSON body (e.g. { "response": { "isDeleted": true } }). They now return 204 with no response body. Check the status code instead of parsing the response.

Affected endpoints:

  • DELETE /api/config-profiles/{uuid}
  • DELETE /api/external-squads/{uuid}
  • DELETE /api/hosts/{uuid}
  • DELETE /api/infra-billing/history/{uuid}
  • DELETE /api/infra-billing/nodes/{uuid}
  • DELETE /api/infra-billing/providers/{uuid}
  • DELETE /api/internal-squads/{uuid}
  • DELETE /api/node-plugins/{uuid}
  • DELETE /api/node-plugins/torrent-blocker/truncate
  • DELETE /api/nodes/{uuid}
  • DELETE /api/passkeys
  • DELETE /api/snippets
  • DELETE /api/subscription-page-configs/{uuid}
  • DELETE /api/subscription-templates/{uuid}
  • DELETE /api/tokens/{uuid}
  • DELETE /api/users/{userId}

Background operations now return 202 Accepted

Operations that are processed asynchronously now return 202 with no response body (previously 200 with a body such as { "response": { "affectedRows": N } }). The number of affected rows is no longer returned.

Affected endpoints:

  • POST /api/external-squads/{uuid}/bulk-actions/add-users
  • DELETE /api/external-squads/{uuid}/bulk-actions/remove-users
  • POST /api/internal-squads/{uuid}/bulk-actions/add-users
  • DELETE /api/internal-squads/{uuid}/bulk-actions/remove-users
  • POST /api/internal-squads/{uuid}/bulk-actions/add-many-users
  • DELETE /api/internal-squads/{uuid}/bulk-actions/remove-many-users
  • POST /api/node-plugins/executor
  • POST /api/nodes/actions/restart-all
  • POST /api/nodes/{uuid}/actions/restart
  • POST /api/users/bulk/all/extend-expiration-date
  • POST /api/users/bulk/all/reset-traffic
  • POST /api/users/bulk/all/update
  • POST /api/users/bulk/delete-by-status
  • POST /api/users/bulk/reset-traffic
  • POST /api/users/bulk/revoke-subscription
  • POST /api/users/bulk/update

POST /api/users/bulk/delete-by-status: the status body field is now explicitly required.


Synchronous operations without a response body now return 204 No Content

These endpoints previously returned 200 with a body; they now return 204 with no response body.

Affected endpoints:

  • POST /api/nodes/bulk-actions
  • POST /api/nodes/bulk-actions/profile-modification
  • POST /api/nodes/bulk-actions/update
  • POST /api/nodes/{uuid}/actions/reset-traffic
  • POST /api/users/bulk/delete
  • POST /api/users/bulk/extend-expiration-date
  • POST /api/users/bulk/update-squads
  • POST /api/hosts/bulk/delete
  • POST /api/hosts/bulk/disable
  • POST /api/hosts/bulk/enable
  • PATCH /api/hosts/bulk/update

Resource-creating POST endpoints now return 201 Created

Previously returned 200. The response body is unchanged.

Affected endpoints:

  • POST /api/node-plugins
  • POST /api/subscription-page-configs
  • POST /api/subscription-templates

POST /api/system/testers/srr-matcher changed in the opposite direction: it now returns 200 instead of 201 (it does not create a resource).


Typed 400, 404 and 500 error responses

Error responses are now documented with shared typed schemas on every endpoint:

  • 400oneOf: RemnawaveBadRequestErrorDto (business errors: timestamp, path, message, errorCode) or RemnawaveValidationErrorDto (validation errors: message, statusCode, errors\\\[\\\]). The previous inline { errors, message, statusCode } object is removed.
  • 404RemnawaveNotFoundErrorDto (now documented on every endpoint)
  • 500RemnawaveInternalServerErrorDto

All possible message and errorCode values are enumerated in the specification per endpoint. The actual runtime error format is unchanged — this is a documentation/typing improvement that benefits generated SDK clients. The catch-all default responses on auth/passkey endpoints were removed.

Affected endpoints: all.


Auth and passkey endpoints: success responses documented

Success responses (200/201) are now documented for the auth and passkey endpoints; previously the specification listed only error responses for them.

Affected endpoints:

  • POST /api/auth/login
  • POST /api/auth/register
  • GET /api/auth/status
  • POST /api/auth/oauth2/authorize
  • POST /api/auth/oauth2/callback
  • GET /api/auth/passkey/authentication/options
  • POST /api/auth/passkey/authentication/verify
  • GET /api/passkeys
  • PATCH /api/passkeys
  • GET /api/passkeys/registration/options
  • POST /api/passkeys/registration/verify

Keygen: pubKey replaced with secretKey

The GET /api/keygen response object now returns secretKey instead of pubKey (GetPubKeyResponseDtoGetNodeSecretKeyResponseDto).

Affected endpoints:

  • GET /api/keygen

IP control module renamed: /api/ip-control/api/connections

All endpoints of the former ip-control controller moved to a new base path with a unified route structure. The old paths were removed without deprecation. Job semantics are unchanged: POST starts a background job and returns a jobId (201), GET with that jobId returns the result (200), drop is fire-and-forget (202). Note that the user-scoped endpoint now takes the numeric userId instead of the user UUID.

Affected endpoints:

  • POST /api/ip-control/fetch-ips/{uuid}POST /api/connections/by-user/{userId}
  • GET /api/ip-control/fetch-ips/result/{jobId}GET /api/connections/by-user/{jobId}
  • POST /api/ip-control/fetch-users-ips/{nodeUuid}POST /api/connections/by-node/{nodeUuid}
  • GET /api/ip-control/fetch-users-ips/result/{jobId}GET /api/connections/by-node/{jobId}
  • POST /api/ip-control/drop-connectionsPOST /api/connections/drop

API token scopes renamed. The ip-control scope resource is now connections:

  • ip-control:\* / ip-control:read / ip-control:writeconnections:\* / connections:read / connections:write
  • ip-control:fetch-ipsconnections:by-user
  • ip-control:fetch-ips-resultconnections:by-user-result
  • ip-control:fetch-users-ipsconnections:by-node
  • ip-control:fetch-users-ips-resultconnections:by-node-result
  • ip-control:drop-connectionsconnections:drop

Scopes stored on existing API tokens are migrated automatically during the upgrade. Integrations that hardcode these scope strings when issuing tokens must switch to the new names.


External squads: responseHeaders split into add/remove

The responseHeaders property was replaced by two properties: responseHeadersAdd (object of header name → value) and responseHeadersRemove (array of header names). This affects the PATCH /api/external-squads request body and the external squad objects in all responses.

Affected endpoints:

  • GET /api/external-squads
  • GET /api/external-squads/{uuid}
  • POST /api/external-squads
  • PATCH /api/external-squads
  • POST /api/external-squads/actions/reorder

Subscription settings: fields removed

The following properties were removed from the subscription settings object (request and response): profileTitle, profileUpdateInterval, supportLink, isProfileWebpageUrlEnabled, happAnnounce, happRouting. The subscriptionSettings object embedded in external squad responses shrank accordingly.

Affected endpoints:

  • GET /api/subscription-settings
  • PATCH /api/subscription-settings

API tokens: docs object removed

The GET /api/tokens response no longer contains the docs object (enabled, scalarPath, swaggerPath); only tokens remains.

Affected endpoints:

  • GET /api/tokens

Pagination, filtering and stricter parameter typing

  • Table query parameters filters, filterModes, globalFilterMode and sorting are now documented on the list endpoints: GET /api/users, GET /api/hwid/devices, GET /api/node-plugins/torrent-blocker, GET /api/subscription-request-history.
  • Pagination parameters size/start gained defaults and min/max limits:
    • GET /api/users — default 25, max 1000
    • GET /api/users/stream — default 250, max 1000
    • GET /api/subscriptions — default 25, max 500
    • GET /api/hwid/devices — default 25, max 1000
    • GET /api/hwid/devices/top-users — default 5, max 100
    • GET /api/subscription-request-history — default 25, max 1000
    • GET /api/node-plugins/torrent-blocker — default 25, max 1000
  • GET /api/infra-billing/history gains start/size pagination parameters.
  • All UUID path parameters across the API now declare format: uuid.
  • GET /api/subscriptions/by-short-uuid/{shortUuid}/rawwithDisabledHosts changed from boolean to string (default "false").

SDK schema renames and new stream message schemas

Request schemas were renamed from *RequestDto to *BodyDto (e.g. CreateUserRequestDtoCreateUserBodyDto), many *ResponseDto schemas were removed because the corresponding endpoints no longer return a body (202/204), and the remaining response schemas were renamed to match the new operations (e.g. GetUserByUuidResponseDtoUserResponseDto, GetAllUsersResponseDtoGetUsersResponseDto, FetchIpsResponseDtoConnectionsByUserResponseDto). This affects generated API clients — regenerate them against the 3.0.0 specification.

The specification also documents the message formats of the Remnawave data streams as standalone schemas: RemnawaveNodeConnectionsStreamMessageDto, RemnawaveSubscriptionRequestStreamMessageDto, RemnawaveUserUsageStreamMessageDto.

Ввиду того, что с версии 3.0.0 Remnawave не выполняет сжатие тела ответа - нужно включить его на стороне реверс прокси.

В Caddy достаточно просто добавить encode - это включит дефолтное сжатие zstd и gzip.

https://REPLACE_WITH_YOUR_DOMAIN {
// success-start
  encode
// success-end
    reverse_proxy * http://remnawave:3000
}

https://SUBSCRIPTION_PAGE_DOMAIN {
// success-start
  encode
// success-end
    reverse_proxy * http://remnawave-subscription-page:3010
}

:443 {
    tls internal
    respond 204
}

В случае Nginx - нужно прописать больше параметров:

server {
    server_name PANEL_DOMAIN;

    listen 443 ssl;
    http2 on;
// success-start
  gzip on;
// success-end

    ...
}

server {
    server_name SUBSCRIPTION_PAGE_DOMAIN;

    listen 443 ssl;
    http2 on;
// success-start
  gzip on;
// success-end

    ...
}

// success-start
# Gzip Compression
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types
    application/javascript
    application/json
    application/manifest+json
    application/xml
    font/opentype
    font/eot
    font/otf
    font/ttf
    image/svg+xml
    text/css
    text/javascript
    text/plain
    text/xml;
// success-end

Если у вас используется какой-то CDN - изучайте его документацию. Обычно в таком случае рекомендуется отключать сжатие на стороне вашего реверс прокси, потому что сжатие применяет сам CDN.

Как обновиться?

[!danger] Внимание
Инструкция ниже написана в первую очередь для тех, кто устанавливал панель и ее компоненты следуя инструкции на сайте (docs.rw).

Если вы устанавливали панель и ее компоненты каким-либо скриптом (автоустановщиком) – обратитесь в его документацию или группу для более точных и детальных инструкций.

Для начала обязательно ознакомьтесь с изменения в самом первом сообщение.

Откройте docker-compose.yml:

cd /opt/remnawave && nano docker-compose.yml

Пролистайте вниз до секции remnawave:

services:
  remnawave:
    image: remnawave/backend:2
    container_name: remnawave
    hostname: remnawave

Замните версию :2 на версию :3

services:
  remnawave:
// success-start
  image: remnawave/backend:3
// success-end
    container_name: remnawave
    hostname: remnawave

Сохраните изменения, и перезапустите панель командой:

cd /opt/remnawave && docker compose pull remnawave && docker compose down && docker compose up -d && docker compose logs -f