Skip to content

App Management

Parameters for controlling app behavior via subscription HTTP headers and lines in the response body.

Delivery Methods

All parameters can be delivered in two ways:

1. HTTP header:

HTTP/2 200
profile-title: Мой VPN
support-url: https://t.me/support

2. Line in the subscription body (a # comment):

#profile-title: Мой VPN
#support-url: https://t.me/support
#profile-update-interval: 6
#announce: Текст объявления
vless://...

Priority: HTTP headers take precedence. Body lines are used as a fallback when the corresponding header is absent. This is especially useful when serving subscriptions via static files (nginx), where custom HTTP headers cannot be set.


Standard Parameters

Subscription Name

The subscription profile name. Maximum 25 characters. Can be passed as text or base64 (UTF-8).

Header:

profile-title: Мой VPN

In the subscription body:

#profile-title: Мой VPN

Base64 with a description (the first line is the name, the rest is the description):

profile-title: base64:0JzQvtC5IFZQTgrQlNC+0LHRgNC+INC/0L7QttCw0LvQvtCy0LDRgtGM

Alternative headers (fallback when profile-title is absent): - subscription-name — alternative subscription name - content-disposition — file name from the header (extensions .txt, .yaml, .yml are stripped automatically)

Subscription Description

A separate header for the description if it is not included in profile-title:

profile-description: Быстрые серверы в Европе

Supports base64: profile-description: base64:...

Subscription Update Interval

The automatic subscription update interval in hours. The value must be a multiple of one hour.

Header:

profile-update-interval: 6

In the subscription body:

#profile-update-interval: 6

Subscription Status

Information about the balance, the amount of traffic used, and the subscription expiration date. Fields are separated by semicolons.

subscription-userinfo: upload=0;download=1073741824;total=10737418240;expire=1700000000
Field Description
upload Outgoing traffic (bytes)
download Incoming traffic (bytes)
total Traffic limit (bytes)
expire Expiration date (Unix timestamp, seconds)

If expire > 32,000,000,000, the value is interpreted as milliseconds and converted to seconds.

A button to open the support page. If the link points to Telegram, the Telegram icon is shown.

Header:

support-url: https://t.me/your_support_bot

In the subscription body:

#support-url: https://t.me/your_support_bot

A button to open the subscription website.

Header:

profile-web-page-url: https://your-site.com

In the subscription body:

#profile-web-page-url: https://your-site.com

Alternative header: homepage

Announcement

A text announcement (up to 200 characters). Can be passed as text or base64.

Header:

announce: Плановое обслуживание 15 марта с 03:00 до 05:00 MSK

Base64:

announce: base64:0J/Qu9Cw0L3QvtCy0L7QtSDQvtCx0YHQu9GD0LbQuNCy0LDQvdC40LU=

Announcement URL (a link, not text):

announce-url: https://example.com/news

In the subscription body:

#announce: Плановое обслуживание 15 марта
#announce-url: https://example.com/news
vless://uuid@server:443#Server

Parameter Summary Table

Header Alternatives Format Body (#) Description
profile-title subscription-name, content-disposition text / base64:... Subscription name
profile-description text / base64:... Subscription description
profile-update-interval number (hours) Update interval
subscription-userinfo key=value;... Traffic statistics
sort-order none / ping / name Server sort order (per-subscription on iOS/Android; global on Desktop)
support-url URL Support link
support-email email Support email — shows an "Email" button in the subscription card (fallback contact). Without this header the button is hidden
profile-web-page-url homepage URL Website link
announce text / base64:... Announcement text
announce-url URL Announcement link
autorouting URL Auto-updated routing profile
routing base64 / link / off Routing profile; the value off disables built-in routing
premium-url URL "Premium" link (in the subscription card, see below)
banner-text text / base64:... Banner text (overrides the panel, see below)
banner-button-text text / base64:... Banner button text
banner-button-url URL Banner button link
banner-bg-color hex (#RRGGBB) Banner background color
banner-button-color hex (#RRGGBB) Banner button color
hide-url 1 / 0 / true / false Hide the subscription URL from Share/Copy/QR/backup (see below)
hide-check 1 / 0 / true / false ✅¹ Hide the Home "Check" button (see below)
per-app-proxy-enable 1 / 0 Enable per-app mode (Android only)
per-app-proxy-mode bypass / proxy Per-app mode
per-app-proxy-list CSV / URL List of package names
fragmentation-enable 1 / 0 TCP fragmentation
fragmentation-length min-max Fragment length range
fragmentation-interval min-max Range of delay between fragments
fragmentation-packets tlshello / 1-3 / all Which packets to apply to
noises-enable 1 / 0 Send noise packets before the handshake
noises-type rand / str / hex Noise content type
noises-packet string Noise payload (format depends on type)
noises-delay min-max ms Range of delay between noise packets
server-address-resolve-enable 1 / 0 Pre-resolve the server address via DoH
server-address-resolve-dns-domain URL DoH server URL
server-address-resolve-dns-ip IP DoH server IP (bootstrap)
no-limit-enabled 1 / 0 (iOS) Enable the memory-tight Network Extension mode — keeps the background process under the iOS 50 MB cap so xhttp transports aren't killed by the system (the VPN doesn't drop). Enable-only (never overrides the user's manual choice)

All headers are case-insensitive (profile-title = Profile-Title).

Body parameters are used as a fallback — HTTP headers always take precedence.

All headers with values support the base64: prefix for passing UTF-8 data without Latin-1 / non-ASCII issues (applies to announce, profile-title, profile-description, subscription-name, per-app-proxy-list, banner-text, banner-button-text).

Android and Desktop additionally accept gzip chains in values (base64:gzip:, gzip:base64:, gzip:) — handy for long per-app-proxy-list. iOS supports base64: only (no gzip).

¹ hide-check works as an HTTP header and via the subscription body (#hide-check:), just like hide-url, but the #hide-check: body marker is read only by Android and iOS — Desktop applies hide-check via the header and Premium config only.

⚠️ Cyrillic in the banner. HTTP headers cannot carry non-ASCII directly. To use non-Latin text in the banner or its button, base64-encode it: banner-text: base64:<base64(UTF-8)> and banner-button-text: base64:<base64(UTF-8)>.


Routing

Routing Profile

A static profile in base64. See routing.md for details.

routing: ://routing/onadd/ewog...base64...

The value off (or the ://routing/off link) fully disables built-in routing:

routing: off

Auto-Updated Routing Profile

A URL source of the routing profile with periodic updates. See autorouting.md for details.

autorouting: https://raw.githubusercontent.com/user/repo/main/profile.json

Routing Source Priority

If a routing profile is specified in several places, the first one found by priority is used:

Priority Source
1 (highest) autorouting header
2 Body — a line with a URL (://autorouting/onadd/, ://autorouting/add/)
3 routing header
4 (lowest) Body — a line with base64 (://routing/onadd/, ://routing/add/, ://routing/)

Important: only ://autorouting/ sets sourceURL and enables auto-update. ://routing/onadd/{url} lines in the subscription body import the profile once, without binding it to a source.


Server Description

An additional caption displayed under the server name (maximum 30 characters). It is appended after title using the ? separator:

vless://uuid@server:443#Сервер1?serverDescription=base64-text

Per-App Proxy (subscription control — Android only)

The Android VpnService allows routing only selected apps through the VPN, or conversely excluding them from the tunnel. The provider can force this mode from the subscription via three headers (Android only). Desktop has the feature too, but it is user-controlled — see the subsection below.

per-app-proxy-enable: 1
per-app-proxy-mode: bypass
per-app-proxy-list: com.android.chrome,org.telegram.messenger

Parameters

Header Value Description
per-app-proxy-enable 1 / 0 Enable per-app mode
per-app-proxy-mode bypass | proxy bypass — the listed apps bypass the VPN. proxyonly they go through the VPN
per-app-proxy-list CSV or URL List of package names separated by commas, newlines, or a URL to a text file

List Format

Inline (CSV or line-based):

per-app-proxy-list: com.android.chrome,org.telegram.messenger,com.google.android.youtube

Base64 (for long lists):

per-app-proxy-list: base64:Y29tLmFuZHJvaWQuY2hyb21lCm9yZy50ZWxlZ3JhbS5tZXNzZW5nZXI=

Remote URL:

per-app-proxy-list: https://example.com/myapps.txt

The file at the URL is plain text with package names, one per line or comma-separated. The client downloads it when applying the subscription and on every update.

Behavior

  • If none of the three fields is set, the user's settings in the app are not overridden.
  • If per-app-proxy-enable is set to 0, per-app mode is disabled even if the user enabled it locally.
  • These headers are read on Android only (the list uses package names).

Per-app on Desktop (Windows / macOS / Linux)

The desktop client also supports per-app split-tunnel, but not via these headers — it is a user setting in the app (the "Split-tunneling" screen). A provider cannot set it from the subscription; the user builds the list by executable names/paths, not package names.

Under the hood Desktop does not touch the system firewall — the rule is written straight into xray routing via the process field (socket-PID lookup, no sniffing). It works for both regular and full-config subscriptions. Windows, macOS and Linux are all supported (the xray core resolves the originating process: GetExtendedTcpTable on Windows, /proc on Linux, libproc on macOS).

TUN mode only

Per-app on Desktop works only when TUN mode is on (xray owns the TUN device itself and can see the originating process). In System Proxy / Proxy Only modes the process cannot be resolved and per-app is not applied.


TCP Fragmentation

Overrides the user's global fragmentation settings for this subscription.

fragmentation-enable: 1
fragmentation-packets: tlshello
fragmentation-length: 10-30
fragmentation-interval: 10-30
Header Value Description
fragmentation-enable 1 / 0 Enable fragmentation
fragmentation-packets tlshello | 1-3 | 1 | all Which TCP packets to apply fragmentation to
fragmentation-length min-max Fragment length range in bytes
fragmentation-interval min-max Range of delay between fragments in ms

The same parameters are available through the Premium API as fragmentEnabled / fragmentPackets / fragmentLength / fragmentInterval — for a Premium subscription, HTTP headers are ignored in favor of API values.


Noise Packets (noises)

Sending random UDP packets before the VPN handshake for obfuscation. Primarily relevant for WireGuard and Hysteria2 on networks with deep packet inspection.

noises-enable: 1
noises-type: rand
noises-packet: 10-20
noises-delay: 10-50
Header Value Description
noises-enable 1 / 0 Enable noise
noises-type rand | str | hex Payload format
noises-packet string Noise packet content; for rand — a length range min-max
noises-delay min-max ms Range of delay between noise packets

Resolving the Server Address via DoH

Bootstrap resolution of the server domain via DNS-over-HTTPS before the tunnel is established. Useful when the provider's DNS spoofs the VPN server address.

server-address-resolve-enable: 1
server-address-resolve-dns-domain: https://common.dot.dns.yandex.net/dns-query
server-address-resolve-dns-ip: 77.88.8.8
Header Value Description
server-address-resolve-enable 1 / 0 Enable DoH resolution
server-address-resolve-dns-domain URL DoH endpoint (usually /dns-query)
server-address-resolve-dns-ip IP The DoH server IP for bootstrap — used before its domain is resolved

The same fields are passed through the Premium API as serverAddressResolveEnable / serverAddressResolveDnsDomain / serverAddressResolveDnsIp.


An additional button in the subscription card — it leads to the provider's purchase page or account dashboard.

premium-url: https://example.com/pricing
Header Value Description
premium-url URL URL of the "Premium" button in the subscription card

If not set, the button is hidden.


Provider Banner

The banner is a prominent strip in the subscription card on the home screen (text + an optional button). It is configured in the premium panel, but the text and button can be overridden via subscription headers — convenient for dynamic announcements without opening the panel.

Display Conditions

The banner is shown when the provider is premium (an active premium subscription) and at least one of:

  1. a banner-text header arrived in the subscription response (a dynamic banner — e.g. via Remnawave Response Rules, without opening the INCY premium panel); or
  2. the banner is enabled in the premium panel (bannerEnabled).

So the banner-text header alone turns the banner on (as long as the provider is premium) — you don't have to open the panel and set bannerEnabled. If banner-text is absent, the banner falls back to the old path (panel bannerEnabled + panel text).

Only premium providers may push a banner via headers: for non-premium subscriptions the banner-* headers are ignored.

Priority: Header → Panel

Each field is resolved as header ?? panel: if the corresponding banner-* header came in the subscription response, it is used; otherwise the value from the panel is used.

banner-text: base64:0JDQutGG0LjRjyEg0KHQutC40LTQutCwIDUw0Js=
banner-button-text: Подробнее
banner-button-url: https://example.com/promo
banner-bg-color: #E53E3E
banner-button-color: #38A169
Header Format Overrides (panel)
banner-text text / base64:... bannerText
banner-button-text text / base64:... bannerButtonText
banner-button-url URL bannerButtonUrl
banner-bg-color hex #RRGGBB bannerBgColor
banner-button-color hex #RRGGBB bannerButtonColor

Both the text (banner-text) and the button text (banner-button-text) support base64: — for Cyrillic/UTF-8 this is required (see the warning above).

The button URL is resolved as premium-urlbanner-button-url → panel: the premium-url header has the highest priority (historically).

If the banner text is empty after resolution, the banner is not shown.

Supported on iOS, Android, and Desktop.


Hiding the Subscription URL from the User

The hide-url parameter prevents the subscription URL from "leaking" off the device: when enabled, the app does not show or allow exporting the URL via Share, Copy URL, QR code, or backups. The subscription name, servers, and all the rest of the UX work as usual — only the URL itself is hidden.

Header:

hide-url: 1

In the subscription body:

#hide-url: 1
vless://...

Premium API (JSON):

{
  "hide_url": true,
  "settings": { ... }
}

Accepted Values

What is sent Behavior
1, true, yes (case-insensitive) URL is hidden
0, false, no, empty string URL is visible (default)
Any other value in the header Ignored, URL is visible

Source Priority

  1. The hide-url HTTP header has the highest priority
  2. The #hide-url: line in the subscription body is used as a fallback when the header is absent
  3. The hide_url field in the Premium API JSON is an independent source applied in parallel

If at least one source says "hide", the URL is hidden. To unhide it, disable it in all sources (or refresh the subscription with the updated value).

What Is Blocked

  • The Share button in the subscription card
  • The Copy URL button
  • Displaying the subscription QR code
  • Including the subscription in a backup (even a password-encrypted one)
  • The export button in the subscription's server editor

What Is NOT Blocked

  • Viewing and editing the server settings within the subscription (on devices with an admin HWID — see admin-hwids.md)
  • Connecting to servers, ping, traffic stats, refreshing the subscription
  • Backups of individual servers (if they were imported manually, outside this subscription)

Rules for Premium Providers

Premium Admin HWID hide-url Sees URL URL in backup
no no yes yes
no yes no no
yes yes no yes yes
yes yes yes yes no (admin sees it, but cannot export via backup)
yes no no no

Without hide-url, regular (non-premium) subscriptions are always exported and copied — hide-url is the only way to forbid this for non-premium.


Hiding the "Check" Button

The hide-check parameter removes the "Check" button (connectivity check while the VPN is active) from the Home screen. It behaves exactly like hide-url: tri-state (set to "hide" / set to "show" / absent → fallback). The button is shown by default.

Useful for providers whose server answers the check request in a non-standard way (or blocks it), so the button would mislead the user.

Header:

hide-check: 1

In the subscription body (Android and iOS only — Desktop ignores the body marker):

#hide-check: 1
vless://...

JSON subscription body:

{ "hide_check": true }

Premium API (JSON):

{
  "settings": { "hideCheck": true }
}

Accepted Values

Sent value Behavior
1, true, yes (case-insensitive) "Check" button hidden
0, false, no, empty string Button shown (default)
Header absent Falls back to body / Premium config, otherwise shown

Source Priority

  1. hide-check HTTP header — highest priority
  2. #hide-check: marker in the subscription body — fallback (Android/iOS)
  3. settings.hideCheck in the Premium API — independent source

Platforms

Android, iOS and Desktop — all three hide the button. The only difference is the "subscription body" source: Desktop does not read the #hide-check: marker (use the header or Premium config).


Settings the Subscription Cannot Set via HTTP Headers

These parameters are stored in the provider's Premium API configuration and are applied by the client only if the subscription domain belongs to a Premium provider. They cannot be enabled "via a subscription without an account in the panel" — this is by design.

Group What is configured Link
Lite Mode Simplified interface, links to bot/channel/support + preset icons premium-api.md § Lite Mode
Subscription banner Text + colors + button in the subscription card premium-api.md § Баннер подписки
Custom theme Flat colors and gradients for the account / background premium-api.md § Кастомная тема
Force settings forceConnectionStyle: classic round button vs compact toggle premium-api.md § Принудительные настройки
Ping and sorting defaultPingProtocol, defaultSortOrder, pingOnUpdate premium-api.md § Ping и сортировка
Domain fronting resolveAddress / hostHeader (the SNI ↔ Host pairing for obfuscation) premium-api.md § Domain fronting и фрагментация
Admin access by HWID adminHwids + push auto-approve admin-hwids.md
Push notifications Moderation, targeting, cancellation provider-notifications.md

Fragmentation, noise, and DoH resolution are available through both channels: subscription HTTP headers (see above) or the Premium API. For a Premium subscription, API values take precedence over headers.