Как оформить подписку в Bloom
Какие заголовки подписки читает приложение Bloom, какими ссылками его открывать, как работает кабинет: подтверждение домена, ответ сервера, логотип и статистика. Всё ниже описывает текущую версию приложения и сервера.
Два способа оформить подписку
Заголовки подписки
бесплатноПанель отдаёт оформление в заголовках ответа подписки: логотип, цвет, кнопки, объявление, баннеры. Bloom показывает его любому пользователю вашей подписки — без регистрации и без кабинета. Список заголовков — ниже.
Кабинет Bloom
по договорённостиТо же оформление, но настраивается на этом сайте, а не в панели: с предпросмотром, историей версий и возвратом к любой из них, статистикой запросов, входом с кодом. Показывается только для доменов, владение которыми вы подтвердили. Условия подключения согласуются с командой Bloom.
Можно и то и другое. Каждое поле, заполненное в кабинете, заменяет такое же из заголовков; пустые поля кабинета берутся из заголовков. Если кабинет перестал отдавать оформление (домен не подтверждён, аккаунт не активен, оплата закончилась), приложение снова показывает оформление из заголовков, а без них — стандартное оформление Bloom.
Заголовки подписки
Bloom читает заголовки ответа на запрос подписки. Имена заголовков — без учёта регистра.
- Текст не латиницей (русский, эмодзи) передавайте как
base64:и текст в UTF-8, закодированный в base64:profile-title: base64:0JzQvtC5IFZQTg==(«Мой VPN»). Заголовки HTTP рассчитаны на латиницу, и без base64 iOS покажет вместо букв мусор. - Ссылки принимаются только
https://,http://,tg://иmailto:. Ссылку с другой схемой (например,bloom://илиvless://) Bloom молча пропускает. - Цвет — шестнадцатеричный:
#5B6CF0,5B6CF0или#5BF; прозрачность в#RRGGBBAAне учитывается. - Bloom представляется заголовком
User-Agent: Bloom/<версия> (iOS <версия>; <модель>; compatible; Happ)(без версии iOS и модели, если пользователь выключил «Передавать ID устройства»), поэтому панели, которые отдают заголовокroutingтолько клиентам Happ, отдают его и Bloom. Если в таком ответе нет серверов, Bloom повторяет запрос без «compatible; Happ».
Подписка
| Заголовок | Что делает в Bloom |
|---|---|
subscription-userinfo | upload=…; download=…; total=…; expire=… — трафик (байты) и срок (Unix-время). Срок дальше 10 лет Bloom считает бессрочным и дату не показывает. |
profile-title | Название подписки (до 100 символов), пока пользователь не переименовал её сам. Без него — имя файла из content-disposition, затем домен ссылки. |
profile-update-interval | Как часто обновлять подписку, в часах (от 1 до 24; без заголовка — раз в час). Действует, когда в Bloom выбрано автообновление «Авто» — так по умолчанию. |
hide-settings: 1 | Не давать пользователю смотреть и копировать ссылки и конфиги серверов. |
Оформление
| Заголовок | Что делает в Bloom |
|---|---|
logo-urlили profile-logo-url, logourl, icon-url, profile-icon-url | Логотип в карточке сервиса на главном экране, при добавлении подписки и в её подробностях. Требования — в разделе «Логотип». |
accent-colorили theme-accent, profile-accent-color | Фирменный цвет кнопок, ссылок и цифр главного экрана. Большая кнопка подключения остаётся в цветах Bloom; в светлой и тёмной теме цвет подстраивается, чтобы текст читался. |
bot-urlили profile-bot-url, boturl | Кнопка «Бот» в карточке сервиса. |
channel-urlили profile-channel-url, channelurl | Кнопка «Канал». |
support-urlили profile-support-url, supporturl | Кнопка «Поддержка». |
profile-web-page-urlили web-page-url, webpageurl, profile-webpage-url | Кнопка «Сайт»; на неё же ведёт «Как продлить», когда подписка закончилась (если нет своей ссылки у блока окончания). |
announce-urlили profile-announce-url, announceurl | Кнопка «Новости». |
Кнопок-капсул в карточке сервиса — не больше шести, в порядке: Бот, Канал, Поддержка, Сайт, Новости, затем свои кнопки из bloom-buttons. Одна и та же ссылка дважды не показывается.
Объявление и свои кнопки
| Заголовок | Что делает в Bloom |
|---|---|
announce | Текст объявления в карточке сервиса и в сообщении провайдера (до 2000 символов, лучше через base64:). |
bloom-buttons | До трёх своих кнопок: Название|https://…;Название|https://… (название — до 40 символов). |
Баннер и окончание подписки
| Заголовок | Что делает в Bloom |
|---|---|
banner-textили banner | Цветной баннер под карточкой сервиса (до 500 символов). Пока подписка закончилась или кончился трафик, баннер не показывается. |
banner-button-text, banner-button-urlили banner-url | Кнопка баннера (без текста — «Подробнее»). Без ссылки кнопки нет. |
banner-bg-colorили banner-color | Цвет баннера. Без него — фирменный цвет (accent-color), а без того — цвет Bloom. |
banner-text-color, banner-button-color | Цвет текста и кнопки. Без них цвет выбирается по фону: на светлом фоне (относительная яркость выше 0,30) текст и кнопка тёмные, иначе белые. |
expiry-banner-text | Текст на главном экране, когда подписка закончилась или кончился трафик — пишите так, чтобы подходило к обоим случаям. |
expiry-banner-button-text, expiry-banner-button-urlили expiry-banner-url | Кнопка на этом экране (без текста — «Как продлить»). Без ссылки она ведёт на сайт, бота или поддержку — что задано, а без них открывает объявление провайдера. |
Маршрутизация и обход блокировок
| Заголовок | Что делает в Bloom |
|---|---|
routing | Профиль маршрутизации в формате Happ: happ://routing/onadd/<base64>, happ://routing/add/<base64> или base64 JSON без ссылки. onadd — профиль может включиться сам, но только если пользователь не выбрал маршрутизацию сам и в профиле нет того, о чём Bloom предупреждает (трафик мимо VPN, сторонний DNS, подмена адресов): иначе он ждёт решения пользователя. add — профиль только появляется в списке. off — не включать профиль провайдера автоматически. Ссылки на гео-файлы в профиле — только https://. |
fragmentation-enable: 1fragmentation-packets, fragmentation-length, fragmentation-interval (или -delay) | Фрагментация TLS для обхода блокировок, например tlshello, 100-200, 10-20. Действует, пока пользователь не настроил обход блокировок сам. |
То же в теле подписки
Если панель не умеет отдавать свои заголовки, часть из них можно положить в тело подписки строками #ключ: значение (тело открытым текстом или в base64). Так читаются profile-title, subscription-userinfo, profile-update-interval, support-url, profile-web-page-url, announce, announce-url, hide-settings и строка happ://routing/…. Заголовок с тем же именем важнее строки в теле. Остальное оформление (логотип, цвет, баннеры, кнопки) — только заголовками или в кабинете.
Пример
profile-title: base64:0JzQvtC5IFZQTg== subscription-userinfo: upload=0; download=1073741824; total=107374182400; expire=1798675200 profile-update-interval: 6 logo-url: https://example-vpn.com/bloom-logo.png accent-color: #5B6CF0 bot-url: https://t.me/example_vpn_bot support-url: https://t.me/example_vpn_support announce: base64:0KHQutC40LTQutCwIDQwJSDQvdCwINCz0L7QtA== expiry-banner-text: base64:0JTQvtGB0YLRg9C/INC30LDQutC+0L3Rh9C40LvRgdGPLiDQn9GA0L7QtNC70LjRgtC1INCyINCx0L7RgtC1Lg== expiry-banner-button-text: base64:0J/RgNC+0LTQu9C40YLRjA== expiry-banner-button-url: https://t.me/example_vpn_bot?start=renew
Новые заголовки пользователь увидит после следующего обновления подписки в приложении — по расписанию из profile-update-interval или когда обновит её сам.
Ссылки, которые открывают Bloom
| Ссылка | Что делает |
|---|---|
bloom://add?url=<ссылка> | Добавить подписку или сервер. Ссылку внутри закодируйте целиком (percent-encoding, как encodeURIComponent), иначе всё после & потеряется. Вместо url можно link или sub. |
bloom://add/<base64> | То же, ссылка в base64 — обычном или URL-safe, с = на конце или без. |
bloom://routing/onadd/<base64>bloom://routing/add/<base64>, bloom://routing/off | Профиль маршрутизации (JSON в формате Happ): добавить и включить, только добавить, выключить маршрутизацию. Сам по ссылке профиль не включается: Bloom показывает, что в нём, и ждёт подтверждения. |
vless://, vmess://, trojan://, ss://, hysteria2://, hy2://, wireguard:// | Bloom зарегистрирован для этих ссылок, но их же занимают другие VPN-приложения — какое откроется, решает iOS. Надёжнее bloom://add. |
Внутри bloom://add подходит ссылка подписки (https://…), ссылка одного сервера (vless://, vmess://, trojan://, ss://, hysteria2://, tuic://, wireguard:// и другие), несколько ссылок серверов и ссылка «добавить подписку» других приложений (happ://add/https://…, v2raytun://import/…, sing-box://import-remote-profile?url=…).
Пример: подписка https://sub.example-vpn.com/api/sub/AbC123 →bloom://add?url=https%3A%2F%2Fsub.example-vpn.com%2Fapi%2Fsub%2FAbC123
Страница «Открыть в Bloom»
Ссылку bloom:// не везде можно нажать: Telegram и многие сайты не делают её ссылкой. Для них есть обычная https-страница, которая открывает Bloom:
https://web-bloom.app/add#https://sub.example-vpn.com/api/sub/AbC123
- Ссылка подписки идёт после
#как есть. Эта часть адреса остаётся в браузере пользователя: ни сервер Bloom, ни сеть доставки перед ним, ни бот, который строит превью ссылки, её не получают. - Страница сразу пробует открыть Bloom и показывает кнопку «Открыть в Bloom», ссылку для ручного копирования и шаги, если Bloom не установлен. Дальше — как с
bloom://add: подписка загрузится только после «Проверить». - Если
#использовать нельзя, естьhttps://web-bloom.app/add?url=<ссылка в percent-encoding>. Такая страница работает и без JavaScript, но ссылка подписки тогда приходит на сервер (и в сеть доставки, если она включена). Сервер Bloom её не записывает и не хранит, но лучше вариант с#.
Собрать ссылку
Ссылка никуда не отправляется: страница собирает её в вашем браузере.
- Страница
- bloom://
Кабинет: подтверждение домена
Оформление из кабинета показывается только для доменов подписки, владение которыми вы подтвердили. В кабинете можно добавить до 20 доменов (или вставить ссылку подписки целиком — домен возьмётся из неё). Для каждого выдаётся код вида bloom-3f9a…; подтвердить можно любым способом:
- TXT-запись в DNS: имя
_bloom-verify.<домен>, значение — код. Сервер спрашивает 1.1.1.1 и 8.8.8.8, затем свой DNS. Изменения DNS иногда применяются до часа. Для IP-адреса вместо домена этот способ не подходит. - HTTP-заголовок в ответе подписки:
bloom-verify: <код>. Сервер запрашиваетhttps://<домен>/или указанную вами ссылку подписки на этом же домене (порт 443, 2053, 2083, 2087, 2096, 8443) сUser-Agent: Bloom-Verify/1.0, читает только заголовки, не ходит по перенаправлениям и не подключается к внутренним адресам. Например, nginx:add_header bloom-verify "bloom-3f9a…" always;, Caddy:header bloom-verify "bloom-3f9a…".
Домен может добавить несколько аккаунтов, но подтверждён он только у одного — у того, кто прошёл проверку последним; прежний владелец теряет подтверждение. Так никто не займёт чужой домен, просто добавив его первым.
Не удаляйте запись после подтверждения
Подтверждённые домены сервер проверяет снова раз в сутки — той же проверкой: подходит и TXT-запись, и заголовок. Если подтверждение не находится 3 раза подряд в течение хотя бы 2 дней, домен получает отметку «подтверждение не найдено с <дата>» — её видите вы и администратор Bloom. Брендинг при этом показывается дальше и автоматически не снимается; снять подтверждение может только администратор. Верните запись или заголовок и нажмите в кабинете «Проверить снова» — отметка исчезнет. Домены, подтверждённые администратором вручную, повторно не проверяются.
Как приложение спрашивает кабинет
Bloom берёт домен из ссылки подписки (https://sub.example-vpn.com/api/sub/… → sub.example-vpn.com) и спрашивает:
GET https://web-bloom.app/v1/branding?host=sub.example-vpn.com
- Когда: при добавлении подписки, при запуске Bloom и возвращении в него, после подключения VPN и после обновления подписок — не чаще раза в 15 минут для каждой подписки. Когда пользователь обновляет подписку сам (кнопка обновления, потянуть экран вниз), Bloom спрашивает сразу. Поэтому изменения из кабинета пользователь видит, когда в следующий раз откроет приложение.
- Ответ 200 — домен подтверждён, аккаунт активен, оплата действует и оформление сохранено. Поля:
name(до 40 символов),logoUrl,accentHex,botUrl,channelUrl,supportUrl,webPageUrl,announceUrl,announce(до 500),bannerиexpiryBanner(текст до 200, кнопка до 30),routingProfileUrl,updatedAt. Пустые поля не передаются. - Ответ 304 — с прошлого раза ничего не изменилось (приложение присылает
If-None-Match). - Ответ 404
{"error":"not_found"}— оформления из кабинета для этого домена нет. Приложение убирает слой кабинета и показывает оформление из заголовков подписки или стандартное.
Профиль маршрутизации из кабинета (routingProfileUrl) — это ссылка https:// на файл профиля Happ (JSON, base64 или happ://routing/onadd/…). Bloom скачивает его сам и использует, только если в заголовках подписки своего профиля нет; правила включения те же, что у заголовка routing.
Пользователь может выключить запросы к серверу Bloom: «Настройки» → «О приложении» → «Оформление от провайдеров». Тогда он видит только оформление из заголовков.
Логотип
Bloom показывает логотип в квадрате со скруглёнными углами (на главном экране — 28 точек, то есть 84 пикселя на большинстве iPhone), заполняя квадрат целиком: у не квадратной картинки края обрежутся. Лучше всего — квадрат от 256×256 пикселей с непрозрачным фоном и запасом по краям.
- В кабинете: PNG, JPEG или WebP, до 512 КБ, от 32 до 1024 пикселей по стороне. Сервер хранит перекодированную копию без метаданных и отдаёт её по постоянному адресу с кэшем на год; после замены прежний файл остаётся доступен, пока на него ссылается версия в истории, и ещё 7 дней.
- Заголовком
logo-url: адресhttps://(илиhttp://) на публичном сервере — адреса домашних и внутренних сетей Bloom не загружает. Картинка до 1 МБ и до 4096 пикселей по стороне, растровая (PNG, JPEG, WebP); SVG не подходит. Телефон хранит уменьшенную копию сутки.
Статистика в кабинете
- Запросы — сколько раз приложение спросило оформление для ваших подтверждённых доменов (ответ «не изменилось» тоже считается). Учитываются только пользователи, у которых включено «Оформление от провайдеров», и только дни начиная с подтверждения домена.
- Устройства — оценка, причём заниженная. За сутки сервер различает запросы по адресу сети и заголовку User-Agent, не сохраняя ни то, ни другое. Bloom присылает одинаковый User-Agent у всех, поэтому все устройства за одним адресом — VPN-сервером, мобильным оператором, домашним роутером — считаются одним. Устройства разных дней не сравниваются, поэтому «за месяц» их не сложить.
- Цифры за сегодня обновляются раз в минуту, статистика хранится 90 дней. IP-адреса не записываются — подробнее в разделе «Конфиденциальность».
Остались вопросы?
Кабинет: создать аккаунт (бесплатно, редактор с предпросмотром доступен сразу) или войти.