Перейти к содержанию

Формат подписки

Описание форматов подписок, поддерживаемых протоколов и HTTP-заголовков.

Поддерживаемые протоколы

Протокол Схема Описание
VLESS vless:// Основной протокол
VMess vmess:// JSON-based конфигурация в base64
Trojan trojan:// Парольная аутентификация
Shadowsocks ss:// SIP002 и современный формат
Hysteria2 hysteria2://, hy2:// Мульти-портовая поддержка
SOCKS5 socks://, socks5:// Проксирование через SOCKS5
HTTP-proxy http://user:pass@host:port HTTP-прокси (со @ — иначе строка считается ссылкой на подписку)
WireGuard wireguard://, wg:// Туннелирование WireGuard
AmneziaWG amneziawg://, awg://, .conf в теле Обфусцированный WireGuard. Одиночный .conf или несколько серверов в одной подписке — см. раздел «AmneziaWG / WireGuard .conf в теле» ниже

Схемы ssr://, tuic://, hysteria:// распознаются приложением, но не парсятся — серверы с этими схемами будут пропущены.

Форматы тела подписки

1. Base64-закодированные ссылки

Наиболее распространённый формат. Тело ответа — base64, при декодировании содержит ссылки по одной на строку:

base64(
  vless://uuid@server1:443?security=tls#Server1
  vless://uuid@server2:443?security=tls#Server2
)

Поддерживается URL-safe Base64 (- → +, _ → /).

2. Открытые ссылки (plain text)

Ссылки в открытом виде, по одной на строку:

vless://uuid@server1:443?security=tls#Server1
vmess://eyJhZGQiOiJzZXJ2ZXIyIn0=
trojan://password@server3:443#Server3
socks://user:pass@server4:1080#Server4
wireguard://secretKey@server5:51820?publickey=KEY&address=10.0.0.2#Server5
amneziawg://<base64url-conf>#Server6

3. JSON-форматы

Массив полных xray-конфигов:

[
    { "outbounds": [...], "routing": {...} },
    { "outbounds": [...], "routing": {...} }
]

Полный xray-конфиг (одиночный объект с inbounds и outbounds):

{
    "inbounds": [...],
    "outbounds": [...],
    "routing": {...},
    "dns": {...}
}

Подробнее: full-xray-config.md.

4. Смешанный формат

Ссылки серверов + строки маршрутизации + метаданные в одном теле:

vless://uuid@server1:443?security=tls#Server1
vless://uuid@server2:443?security=tls#Server2
://autorouting/onadd/https://example.com/routing.json
#announce: Плановое обслуживание завтра

Поддерживаемые специальные строки в теле:

Паттерн Описание
://autorouting/onadd/{url} Автообновляемый профиль маршрутизации (URL, с sourceURL)
://autorouting/onadd/{base64} Профиль маршрутизации inline (base64)
://autorouting/add/{url} Автообновляемый профиль маршрутизации (URL, с sourceURL)
://routing/onadd/{url} Одноразовый импорт профиля по URL (без автообновления)
://routing/onadd/{base64} Статический профиль маршрутизации
://routing/add/{base64} Статический профиль маршрутизации
://onadd/{url или base64} Сокращённая форма (без автообновления)
://routing/{base64} Сокращённая форма
#announce: текст Объявление (поддерживает base64:...)
#profile-title: текст Имя подписки (поддерживает base64:...)
#support-url: URL Ссылка на поддержку
#profile-web-page-url: URL Ссылка на сайт провайдера
#announce-url: URL Ссылка на объявление
#profile-update-interval: число Интервал обновления (часы)

Специальные строки извлекаются из тела и не попадают в список серверов.

Приоритет: значения из HTTP-заголовков имеют приоритет над значениями из тела. Inline-метаданные в теле используются как fallback, если соответствующий заголовок отсутствует.

5. AmneziaWG / WireGuard .conf в теле

Тело подписки может быть сырым .conf-файлом WireGuard или AmneziaWG (многострочный INI с секциями [Interface] и [Peer]). Приложение распознаёт его по наличию [Interface] + PrivateKey и роутит в тот же парсер, что файл/«Вставить». AmneziaWG определяется по наличию обфускационных параметров (Jc, Jmin, Jmax, S1–S4, H1–H4, I1–I5).

Поддерживаются также новые параметры AmneziaWG 3.0 и 3.1 (движок обновлён до amneziawg-go v3.1). Все они опциональны и прокидываются в движок как есть:

Ключ .conf Версия Описание
HeaderProtectionKey 3.0 Ключ защиты заголовков пакетов (задаётся сервером; для работы S1–S4 должны быть ≥ 12). Принимается в base64 (как выдаёт awg genkey) или в hex
ContentPaddingAddition 3.0 Диапазон случайного паддинга контента (uint32 или диапазон min-max)
RekeyAfterTime 3.0 Время (сек), после которого клиент инициирует пересогласование
RekeyTimeout 3.0 Таймаут (сек) повтора рукопожатия
RejectAfterTime 3.0 Время (сек), после которого клиент принудительно пересогласовывается и отклоняет входящие данные
KeepaliveTimeout 3.0 Время (сек) от последней отправки данных до отправки keepalive
MaxHandshakeAttempts 3.0 Максимальное число повторов рукопожатия
RandomTrailers 3.1 Случайные «хвосты» у пакетов. По умолчанию выключено
DisableCookies 3.1 Отключает cookie-механизм WireGuard. По умолчанию выключено
[Interface]
PrivateKey = <base64>
Address = 10.8.0.2/32
DNS = 1.1.1.1
Jc = 4
Jmin = 40
Jmax = 70
S1 = 86
S2 = 574
H1 = 1234567890

[Peer]
PublicKey = <base64>
PresharedKey = <base64>
AllowedIPs = 0.0.0.0/0
Endpoint = server.example.com:51820

Секция [Device]. AmneziaWG 3.x выносит обфускацию и тюнинг в отдельную секцию [Device]. Она поддерживается наравне с [Interface] — обе описывают одно и то же устройство, так что ключи из таблицы выше можно класть в любую из них:

[Device]
Jc = 4
S1 = 12
S2 = 12
HeaderProtectionKey = <hex>
RandomTrailers = true

[Interface]
PrivateKey = <base64>
Address = 10.8.0.2/32

[Peer]
PublicKey = <base64>
AllowedIPs = 0.0.0.0/0
Endpoint = server.example.com:51820

[Interface] остаётся обязательной — в ней лежит PrivateKey. Конфиг из одной только [Device] отвергается.

Форматы значений. Клиент нормализует то, что реально встречается в серверных .conf:

Тип Принимается Уходит в движок
Булев (RandomTrailers, DisableCookies) on/off, yes/no, true/false, 1/0, enabled/disabled true / false
Диапазон (PersistentKeepalive, ContentPaddingAddition, тайминги, H1–H4) 25 или 25-35 (правая граница ≥ левой) как есть
32-байтный ключ (PrivateKey, PublicKey, PresharedKey, HeaderProtectionKey) base64 или hex hex

Начиная с AmneziaWG 3.x PersistentKeepalive может быть диапазоном — интервал keepalive выбирается случайно внутри него.

Тело может быть как plain-text, так и base64-обёрнутым. То же самое можно доставить через deep-link incy://import/{base64-conf} — см. deep-links.md.

Сырой .conf в теле парсится как одна серверная запись; обфускация AmneziaWG применяется движком на этапе подключения (клиент хранит .conf дословно).

Несколько AmneziaWG-серверов в одной подписке

Только iOS и Android. Desktop-клиент AmneziaWG не поддерживает — .conf в теле там парсится как обычный WireGuard, а схемы amneziawg:///awg:// и JSON-контейнер игнорируются.

Одиночный .conf = один сервер. Чтобы отдать несколько AmneziaWG-локаций одной подпиской, используйте один из двух форматов. В обоих каждый .conf кодируется в url-safe base64 (-→+, _→/, паддинг необязателен), а имя сервера берётся из #-фрагмента или поля name.

Формат 1 — построчный (amneziawg:// / awg://). По одной ссылке на строку, можно мешать с vless:// и другими протоколами в том же теле:

amneziawg://<base64url-conf>#Германия
awg://<base64url-conf>#Нидерланды

amneziawg:// — канонический, awg:// — короткий алиас (эквивалентны). Всё после # — отображаемое имя.

Формат 2 — JSON-контейнер. Тело — JSON-объект с type: "amneziawg":

{
  "type": "amneziawg",
  "version": 1,
  "servers": [
    { "name": "Германия",    "config": "<base64url-conf>" },
    { "name": "Нидерланды",  "config": "<base64url-conf>" }
  ]
}

Каждый элемент servers[] → отдельный сервер. name необязателен (при отсутствии имя берётся из # Name= внутри .conf или из хоста Endpoint). Поле version зарезервировано и сейчас не проверяется.

Этот же контейнер можно положить элементом JSON-массива — рядом с полными xray-конфигами. Так одна подписка отдаёт и VLESS-локации, и AmneziaWG:

[
  { "remarks": "🇵🇱 Poland | TCP", "inbounds": [ /* ... */ ], "outbounds": [ /* ... */ ] },
  { "remarks": "🇩🇪 Germany | XHTTP", "inbounds": [ /* ... */ ], "outbounds": [ /* ... */ ] },
  {
    "type": "amneziawg",
    "version": 1,
    "servers": [
      { "name": "Германия",   "config": "<base64url-conf>" },
      { "name": "Нидерланды", "config": "<base64url-conf>" }
    ]
  }
]

Порядок сохраняется: AmneziaWG-серверы встают в список там, где стоит контейнер. Контейнеров в массиве может быть несколько.

Поведение в обоих форматах: битая base64-запись пропускается — остальные серверы всё равно загружаются (одна плохая локация не ломает всю подписку). Дубликаты по одинаковому .conf схлопываются в один сервер. При обновлении подписки серверы добавляются/обновляются/удаляются без задвоения. HTTP-заголовки остаются на уровне подписки (общие для всех серверов).


Показ серверов по типу сети (Premium)

В Premium-подписке можно показывать разные серверы для Wi-Fi и мобильной сети. Функция реализована в iOS, Android и Desktop (incy-linux), на главной странице и в списке серверов.

Добавьте в название сервера одну из точных меток:

Метка в названии Wi-Fi / Ethernet Мобильная сеть
only Wi-Fi Показывается Скрывается
only Mobile Скрывается Показывается
Без метки Показывается Показывается

Например: Germany only Wi-Fi и Germany only Mobile. Метка может находиться в любой части названия и остаётся видимой пользователю.

Условия и ограничения:

  • У подписки должен быть активен Premium. Без него метки не скрывают серверы.
  • Регистр, пробел и дефис важны: WiFi only, WIFI only, LTE only и only LTE не распознаются. Используйте именно only Wi-Fi или only Mobile.
  • only Mobile относится ко всей мобильной сети, включая LTE/4G и 5G, а не только к LTE.
  • Ethernet считается проводной сетью и обрабатывается как Wi-Fi. Если тип сети не определён, фильтр ничего не скрывает.
  • На Desktop тип сети определяется по сетевым интерфейсам, с проверкой примерно раз в 10 секунд. При нестандартных именах интерфейсов определение может быть неточным. Подключение к точке доступа телефона по Wi-Fi считается Wi-Fi.
  • Используйте только одну метку на сервер. Это фильтр отображения; метки не задают правила маршрутизации и не гарантируют автоматического переподключения при смене сети.

Пример share-ссылок

Имя передаётся после #. Пробелы в ссылке кодируются как %20; проверяется декодированное название:

vless://00000000-0000-4000-8000-000000000001@wifi.example.com:443?encryption=none&security=tls&type=tcp#Germany%20only%20Wi-Fi
vless://00000000-0000-4000-8000-000000000002@mobile.example.com:443?encryption=none&security=tls&type=tcp#Germany%20only%20Mobile

Замените UUID и адреса на параметры своих серверов. Для base64-подписки сначала добавьте метки в имена ссылок, затем закодируйте тело подписки как обычно.

Пример JSON-подписки

В полном Xray-конфиге задайте имя через верхнеуровневое поле remarks:

{
  "remarks": "Germany only Mobile"
}

Это фрагмент метаданных, а не готовая конфигурация: добавьте remarks к своему объекту с inbounds и outbounds. В массиве конфигураций метка задаётся отдельно для каждого объекта. Она относится ко всей отображаемой записи, а не к отдельным outbound внутри балансировщика.


HTTP-заголовки

Заголовки подписки

Заголовок Тип Описание
profile-title string Имя подписки (до 25 символов). Поддерживает base64
subscription-name string Альтернатива profile-title (fallback)
profile-description string Описание подписки. Поддерживает base64
profile-update-interval int Интервал обновления в часах
subscription-userinfo string Статистика трафика и срок действия
support-url URL Ссылка на поддержку
support-email email Email поддержки — показывает кнопку «Email» в карточке подписки. Без заголовка кнопка не показывается
profile-web-page-url URL Ссылка на сайт провайдера. Альтернатива: homepage
homepage URL Fallback для profile-web-page-url
announce-url URL Ссылка на объявление
announce string Текст объявления (до 200 символов). Поддерживает base64
autorouting string Профиль маршрутизации с автообновлением. Ссылка целиком, со схемой: incy://autorouting/onadd/https://… (голый URL не работает)
routing string Профиль маршрутизации (base64 или полная ссылка)
sort-order string Порядок сортировки серверов: ping, name, none
content-disposition string Fallback для имени подписки (расширения .txt, .yaml удаляются)
premium-url URL Ссылка кнопки «Премиум» в карточке подписки
hide-url 1/0/true/false Скрыть URL подписки от Share/Copy/QR/backup
banner-text string Текст баннера (base64). Перебивает панель
banner-button-text string Текст кнопки баннера
banner-button-url URL Ссылка кнопки баннера
banner-bg-color hex Цвет фона баннера (#RRGGBB)
banner-button-color hex Цвет кнопки баннера (#RRGGBB)
fragmentation-enable 1/0 TCP-фрагментация
fragmentation-length min-max Диапазон длины фрагмента
fragmentation-interval min-max Диапазон задержки между фрагментами
fragmentation-packets tlshello / 1-3 / all На какие пакеты применять
noises-enable 1/0 Отправка шумовых пакетов до handshake
noises-type rand / str / hex Тип шумового контента
noises-packet string Payload шума (формат зависит от type)
noises-delay min-max мс Диапазон задержки между шумами
server-address-resolve-enable 1/0 Предварительный DNS-резолв адреса сервера через DoH
server-address-resolve-dns-domain URL URL DoH-сервера
server-address-resolve-dns-ip IP IP DoH-сервера (bootstrap)
no-limit-enabled 1/0 (iOS) Память-экономный режим Network Extension (держит фоновый процесс под лимитом iOS 50 МБ). Только включает
per-app-proxy-enable 1/0 (только Android) Включить per-app режим
per-app-proxy-mode bypass / proxy (только Android) Режим per-app
per-app-proxy-list CSV / URL (только Android) Список package names

Это справочник заголовков подписки. Полное описание каждого (форматы значений, условия показа, приоритет «заголовок → панель», поддержка #-фрагмента в теле) — в Управление приложением, где сводная таблица является авторитетным источником.

Profile Title

Поддерживает два формата:

Открытый текст:

profile-title: My VPN

Base64 с описанием:

profile-title: base64:TWVNdiBWUE4KV2VsY29tZSB0byBvdXIgc2VydmljZQ==

При base64-декодировании: первая строка — имя, остальные — описание.

Subscription User Info

subscription-userinfo: upload=0;download=1073741824;total=10737418240;expire=1735689600
Поле Тип Описание
upload int Исходящий трафик (байт)
download int Входящий трафик (байт)
total int Лимит трафика (байт)
expire int Дата истечения (Unix timestamp, секунды)

Если expire > 32000000000 — значение интерпретируется как миллисекунды и конвертируется в секунды.

Скрытие блока трафика:

Если сервер возвращает subscription-userinfo: 0, блок трафика на главном экране полностью скрывается. Используйте это, когда статистика трафика не предоставляется.

Announce

Текст объявления отображается на главном экране в виде баннера. Поддерживается до 5 строк текста, после чего текст обрезается с многоточием.

announce: Обновление серверов 15 марта
announce: base64:0J7QsdC90L7QstC70LXQvdC40LUg0YHQtdGA0LLQtdGA0L7Qsg==

Sort Order

Задаёт порядок сортировки серверов. На iOS и Android значение применяется к этой подписке (у каждой подписки свои настройки пинга/сортировки/стиля, как и профиль маршрутизации); пользователь может переопределить его в настройках подписки. На Desktop применяется к глобальной настройке сортировки.

sort-order: ping
Значение Описание
none Порядок по умолчанию (как в подписке)
ping По пингу (самые быстрые первыми)
name По алфавиту

Заголовки запроса (клиент → сервер)

При обновлении подписки приложение отправляет:

Заголовок Описание
User-Agent INCY/<version>/<platform>
Accept */*
Accept-Language Language-tag устройства (напр. ru-RU)
Accept-Encoding Только iOS: gzip, deflate, br
x-app-version Версия приложения
x-device-locale Язык устройства
x-client INCY

При включённой отправке HWID дополнительно:

Заголовок Описание
x-hwid Аппаратный идентификатор (подробнее)
X-Device-ID Alias для x-hwid на Android (некоторые сервер-стеки ожидают именно этот заголовок)
x-device-os Платформа (iOS, Android, Linux, Windows)
x-ver-os Версия ОС
x-device-model Модель устройства

Все заголовки HTTP регистронезависимы. Сервер может смотреть на x-hwid либо X-HWID — придут одни и те же байты.


Резервные хосты (fallback)

Если основной хост подписки недоступен (сеть/таймаут/5xx/429), клиент перебирает резервные хосты — тот же путь и токен, меняется только хост. На 404/410 (подписка удалена провайдером) перебор не выполняется. Список резервных хостов приходит не через заголовок, а в теле premium-конфига (settings.fallbackHosts) — см. premium-api.md.