Лендинги
Создайте link-in-bio воронку для каждого домена — гео-сегменты, стопки кнопок, баннер-уведомление и фон — затем сделайте предпросмотр и опубликуйте.
Лендинг — это публичная воронка, которую TEASE отдаёт на одном из ваших доменов. Вы собираете её из упорядоченных гео-сегментов, стопки кнопок для каждого сегмента, необязательного баннера-уведомления и фона — всё это редактируется как черновик, просматривается вживую, а затем публикуется одним атомарным шагом.
Любое изменение, которое вы делаете через API, записывается только в состояние черновика. Боевая страница не меняется,
пока вы не вызовете /publish. Это даёт безопасный цикл «редактирование — предпросмотр — выпуск»
с единым глобальным откатом (/discard).
Собрать страницу
Подключить домен
Выпустить
Концепции
| Концепция | Что это |
|---|---|
| Домен | Хост, на котором отдаётся ваша публичная страница (например, links.creator.com). Любой другой ресурс на этой странице привязан к домену. |
| Гео-сегмент | Упорядоченная корзина аудитории, сопоставляемая по стране (и, опционально, по устройству, ОС, времени или языку). У каждого сегмента своя стопка кнопок. Ровно один сегмент является дефолтным catch-all. |
| Кнопка | Помеченная ссылка внутри сегмента, с видимым текстом, иконкой и URL назначения. Кнопки упорядочены внутри сегмента. |
| Всплывающая подсказка | Необязательная карточка у конкретной кнопки (фото + короткий текст), которая выезжает под кнопкой после задержки. |
| Баннер-уведомление | Push-подобный баннер (аватар, заголовок, текст, призыв к действию), который появляется на странице после небольшой задержки. |
| Фон | Подложка страницы — мобильная картинка, десктопная картинка и сплошной цвет холста за карточкой на десктопе. |
| UI-стиль страницы | Внешний вид кнопок на всём лендинге, вид карточки профиля плюс необязательный гейт 18+ — применяется, пока домен использует встроенный (платформенный) дизайн. |
| Черновик / Опубликованное | Два снимка всей страницы. Вы всегда редактируете черновик; /publish копирует черновик → опубликованное; /discard копирует опубликованное → черновик (откат). |
Аутентификация
Каждый endpoint на этой странице находится по адресу https://app.tease.link и требует Bearer-ключ со
scope write (чтения принимают любой ключ). См. Аутентификацию.
Несколько endpoint-ов только для владельца отмечены прямо в тексте.
Домены
Запись домена — это якорь для всего лендинга. Получите список доменов, которыми вы владеете, создавайте новые и копируйте готовую страницу на другой домен.
Список доменов
curl https://app.tease.link/api/admin/domains \
-H "Authorization: Bearer $TEASE_API_KEY"const res = await fetch('https://app.tease.link/api/admin/domains', {
headers: { Authorization: `Bearer ${process.env.TEASE_API_KEY}` },
});
const { items } = await res.json();import os, requests
res = requests.get(
"https://app.tease.link/api/admin/domains",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
)
items = res.json()["items"]{
"items": [
{
"hostname": "links.creator.com",
"display_name": "Instagram bio",
"created_at": 1751280000,
"button_count": 4,
"infra_state": "ssl_active",
"provisioning_error": null,
"infra_attempted_at": 1751280000
}
]
}Каждая запись несёт infra_state, который управляет статус-бейджем в дашборде:
infra_state | Значение |
|---|---|
unmanaged | Голая запись домена без управляемого сертификата. |
provisioning | Настройка выполняется (выпуск TLS) сразу после создания. |
pending_dns | Ожидание, пока DNS укажет на TEASE — см. кастомные домены. |
ssl_active | Сертификат выпущен, и страница отдаётся по HTTPS. |
failed | Последняя попытка настройки не удалась; provisioning_error содержит сообщение. |
Создать домен
curl -X POST https://app.tease.link/api/admin/domains \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "hostname": "links.creator.com", "display_name": "Instagram bio" }'const res = await fetch('https://app.tease.link/api/admin/domains', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TEASE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ hostname: 'links.creator.com', display_name: 'Instagram bio' }),
});
const domain = await res.json();res = requests.post(
"https://app.tease.link/api/admin/domains",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
json={"hostname": "links.creator.com", "display_name": "Instagram bio"},
)
domain = res.json()Параметры
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
hostname | string | да | Валидный хост (my-site.com), 1–253 символа, в нижнем регистре. Без схемы, без пути. |
display_name | string | нет | Дружелюбная метка «источника трафика», показываемая в отчётах (например, FB Agency). Пустое значение очищает её. |
Новый домен создаётся с infra_state: "provisioning" и засеивается тремя дефолтными
гео-сегментами плюс пустыми записями уведомления/фона, так что он сразу доступен для редактирования. Повторное создание
хоста, которым вы уже владеете, в течение минуты возвращает существующую запись (идемпотентный повтор); иначе
дубликат возвращает 409 domain_taken.
Лимиты тарифа
Каждый тариф ограничивает количество доменов, которыми вы можете владеть. Создание сверх лимита возвращает
409 domain_cap_reached.
Переименовать или удалить домен
PATCH обновляет display_name (это только отчётные метаданные, и они вступают в силу без
публикации). DELETE удаляет домен и каскадно удаляет его кнопки, сегменты, баннер и фон.
# Rename
curl -X PATCH https://app.tease.link/api/admin/domains/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "display_name": "TikTok bio" }'
# Delete
curl -X DELETE https://app.tease.link/api/admin/domains/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY"await fetch('https://app.tease.link/api/admin/domains/links.creator.com', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.TEASE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ display_name: 'TikTok bio' }),
});requests.patch(
"https://app.tease.link/api/admin/domains/links.creator.com",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
json={"display_name": "TikTok bio"},
)Скопировать страницу на другой домен
copy-from заменяет черновые кнопки и сегменты целевого домена копиями из домена-source —
полный клон черновика, который вы затем публикуете. Страница пересобирается со свежими идентичностями кнопок, чтобы
боевая страница обновилась чисто.
curl -X POST https://app.tease.link/api/admin/domains/new-site.com/copy-from \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "source": "links.creator.com" }'| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
source | string | да | Хост, с которого копируется черновая страница. Должен отличаться от целевого. |
Сопутствующие endpoint-ы копируют одну часть между доменами: copy-notification-from (баннер) и
copy-bg-from (фон). POST /api/admin/bulk/copy-content копирует выбранные части
(buttons_segments, bg, notification, canvas_color) из одного источника на множество целей за
один вызов.
Кастомные домены
Чтобы отдавать страницу на собственном домене, подключите его и подтвердите DNS. Подключение — это маленький конечный автомат,
построенный на infra_state: запрос на подключение открывает домен в pending_dns, а успешная
проверка переводит его в активное состояние.
Начните подключение
POST /api/admin/domains/connect регистрирует хост и возвращает точную DNS-запись, которую нужно добавить.
Поддомен (например, links.creator.com) получает инструкцию для CNAME; голый apex (например, creator.com)
получает инструкцию для A-записи. Ответ также включает URL для вызова проверки.
curl -X POST https://app.tease.link/api/admin/domains/connect \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "hostname": "links.creator.com" }'{
"domain_id": 42,
"hostname": "links.creator.com",
"is_apex": false,
"state": "pending_dns",
"instructions": { "record_type": "CNAME", "name": "links", "value": "…" },
"verify_url": "/api/admin/domains/42/verify"
}| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
hostname | string | да | Кастомный хост для подключения. Уже занятый хост возвращает 409 domain_taken. |
provider | string | нет | Подсказка о DNS-провайдере, чтобы возвращаемые инструкции совпадали с интерфейсом вашего регистратора. |
Добавьте DNS-запись
В вашем DNS-провайдере создайте запись точно так, как она возвращена в instructions. CNAME-записи могут
распространяться несколько минут; apex A-записи могут занять больше времени.
Проверьте
Вызовите verify_url (или POST /api/admin/domains/{domain_id}/verify). Пока DNS ещё не подхватился,
ответ остаётся в pending_dns и перечисляет, чего ещё не хватает, в issues:
{
"domain_id": 42,
"hostname": "links.creator.com",
"state": "pending_dns",
"issues": ["CNAME not found"]
}Как только запись разрешается корректно, проверка переводит домен в активное состояние и возвращает боевой URL:
{
"domain_id": 42,
"hostname": "links.creator.com",
"state": "active",
"url": "https://links.creator.com"
}Конечный автомат намеренно мал — из pending_dns есть только два исхода:
| Состояние | Как вы туда попадаете | Что это значит |
|---|---|---|
pending_dns | После connect и после любого verify, пока DNS ещё не корректен. | TEASE ждёт вашу DNS-запись. |
active | После verify, где DNS-запись разрешается корректно. | Страница отдаётся по HTTPS на вашем домене. |
Перезапускайте verify сколько угодно — он идемпотентен и безопасен для опроса, пока распространяется DNS.
Сегменты
Гео-сегмент — это корзина аудитории. Посетители сопоставляются с первым сегментом, чьи условия подходят, проваливаясь к единственному дефолтному catch-all. У каждого сегмента своя упорядоченная стопка кнопок, так что вы можете показывать разную воронку, скажем, мобильному трафику из США, и всем остальным.
Сегмент сопоставляется в первую очередь по стране. Опционально вы можете сузить его условиями отображения по устройству, ОС или времени суток и пометить целевым языком для авто-перевода.
У сегментов своя вкладка «Сегменты» в хабе домена (/domains/<домен>/segments), рядом с «Кнопками».
Там все сегменты — карточками в порядке приоритета (кто выше, тот матчится первым): их страны и условия,
флаги «по умолчанию» / «блок», A/B-набор кнопок и стрелки приоритета. Сами кнопки сегмента
по-прежнему настраиваются во вкладке «Кнопки».
Тиры стран
У аккаунта есть три переиспользуемых тира стран, общих для всех доменов:
- Tier 1 — ваши топовые платящие рынки.
- Tier 2 — средние рынки.
- Блок-лист — страны, которым вы показываете
403(они не попадают в воронку).
Они делают две вещи: пресеты T1 / T2 в редакторе сегмента добавляют страны из вашего Tier 1 / Tier 2 в собираемый сегмент, а трафик автоматически делится по тиру в A/B (Tier 1 сильнее склоняется к платному офферу, чем Tier 2).
Тиры остаются «за кулисами» — они питают пресет-чипы и A/B-деление, а не отдельный экран настроек.
У каждого аккаунта разумные значения по умолчанию; чтобы их изменить, используйте API/MCP
get_config / set_config (ключ geo_classify — { "tier1": [...], "tier2": [...], "blocklist": [...] }
из ISO-3166 alpha-2 кодов). Ваши изменения касаются только вашего аккаунта.
Список сегментов
curl https://app.tease.link/api/admin/segments/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY"{
"domain": "links.creator.com",
"items": [
{
"segment_id": "s_1a2b3c4d",
"domain": "links.creator.com",
"name": "US mobile",
"countries": ["US"],
"position": 0,
"is_default": false,
"match": [{ "type": "device", "op": "is", "values": ["mobile"] }],
"ab": null,
"lang": ""
},
{
"segment_id": "s_default",
"domain": "links.creator.com",
"name": "Everyone",
"countries": [],
"position": 1,
"is_default": true,
"match": null,
"ab": null,
"lang": ""
}
]
}| Поле | Тип | Описание |
|---|---|---|
segment_id | string | Стабильный id (s_<hex>). Используется как tier при управлении кнопками этого сегмента. |
name | string | Метка, которую вы выбираете. |
countries | string[] | Коды ISO-3166 alpha-2, на которые нацелен этот сегмент. Пусто = без ограничения по стране. |
position | int | Порядок, в котором рассматриваются сегменты. |
is_default | bool | Является ли этот сегмент catch-all. Ровно один сегмент на домен является дефолтным. |
match | object[] | null | Необязательные условия отображения (устройство / ОС / время). null = только страна. |
ab | object | null | Необязательная A/B-конфигурация набора кнопок для сегмента. |
lang | string | Необязательный целевой язык (ISO-код) для авто-перевода, или "". |
Создать сегмент
curl -X POST https://app.tease.link/api/admin/segments/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "US mobile",
"countries": ["US"],
"match": { "all": [{ "type": "device", "op": "is", "values": ["mobile"] }] }
}'Параметры
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
name | string | да | 1–64 символа. |
countries | string[] | нет | Коды ISO-3166 alpha-2 (US, GB). Дедуплицируются и приводятся к верхнему регистру. Пусто = без ограничения по стране. |
is_default | bool | нет | Сделать этот сегмент catch-all. Первый сегмент на домене всегда становится дефолтным. |
match | object | нет | Условия отображения, { "all": [<clause>, …] }. Условия объединяются через AND. Опустите для сопоставления только по стране. |
lang | string | нет | Код целевого языка для авто-перевода (см. переводы). |
Условия match
Условие match сужает сегмент за пределы страны. Каждое условие — одно из:
| Условие | Форма | Допустимые значения |
|---|---|---|
device | { "type": "device", "op": "is" | "is_not", "values": [...] } | mobile, tablet, desktop |
os | { "type": "os", "op": "is" | "is_not", "values": [...] } | ios, android, windows, macos, other |
time | { "type": "time", "tz": "<IANA tz>", "days": [0–6], "hours": [[start, end]] } | days 0=Пн…6=Вс; hours — полуоткрытые диапазоны [start, end), где start меньше end, оба 0–24 |
Внутри условия values объединяются через OR; между условиями в all условия объединяются через AND.
Дефолтный сегмент — это catch-all
Каждый домен держит ровно один дефолтный сегмент. Повышение другого сегмента до дефолтного
(is_default: true) автоматически снимает флаг с предыдущего; вы не можете снять единственный
дефолтный напрямую.
Редактировать, переупорядочить, удалить
PATCH принимает любое подмножество полей создания. Опущенное поле остаётся неизменным; отправка
явного пустого набора условий очищает его.
# Edit
curl -X PATCH https://app.tease.link/api/admin/segments/links.creator.com/s_1a2b3c4d \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "countries": ["US", "CA"] }'
# Reorder — the list must be a permutation of the domain's current segment ids
curl -X PUT https://app.tease.link/api/admin/segments/links.creator.com/order \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "order": ["s_1a2b3c4d", "s_default"] }'
# Delete — pass ?force=true to also remove the segment's buttons
curl -X DELETE "https://app.tease.link/api/admin/segments/links.creator.com/s_1a2b3c4d" \
-H "Authorization: Bearer $TEASE_API_KEY"Порядок важен: сегменты рассматриваются сверху вниз, поэтому размещайте наиболее специфичные сегменты выше
catch-all. Переупорядочивание проверяет, что ваш массив order — это в точности текущий набор id сегментов
(иначе order_mismatch). Удаление сегмента, у которого ещё есть кнопки, возвращает
409 segment_has_buttons, если только вы не передадите ?force=true; удаление дефолтного возвращает
400 segment_default_required, пока вы сначала не повысите другой сегмент.
Прямые редиректы
Иногда лендинг — лишний слой для аудитории: посетитель нужен сразу на назначении. Это
закрывают два уровня прямых 307-редиректов, и оба оставляют каждый переход учтённым и
атрибутированным, как обычный клик.
Сегменты-редиректы
Сегмент может быть помечен как сегмент-редирект: совпавший с ним посетитель не видит лендинг —
его сразу 307-редиректит на назначение главной кнопки этого сегмента (самой нижней — той же,
что лендинг красит основным CTA). Переход записывается как клик со своим источником, поэтому
редиректнутые страны видны в отчётах трафика и питают
TG-атрибуцию. Блок-сегмент всегда сильнее редиректа —
заблокированная страна по-прежнему получает 403. Сам флаг включает платформа для гео-маршрутов в
мессенджер; в редакторе сегментов такого переключателя пока нет.
Адрес живёт в КНОПКЕ (исправлено 2026-07-27)
До 27 июля 2026 адрес брался из серверной настройки TG_DIRECT_ACCOUNT_USERNAME — один
Telegram-аккаунт на всю платформу, и только для доменов владельца платформы: у арендатора
сегмент-редирект не работал вовсе, а кнопки сегмента не участвовали вообще (правка кнопки не
меняла на сайте ничего). Теперь цель — та же главная кнопка, что и у доменного
direct-redirect: свой адрес у каждого креатора, видимый и правимый из панели. Нет видимой кнопки
с адресом → отдаётся лендинг (fail-safe).
В панели у такой аудитории метка «→ редирект», над списком кнопок — плашка с настоящим адресом, целевая кнопка подписана, остальные погашены.
Режим direct-redirect (на домен)
Целый домен может пропускать свой лендинг: при включённом режиме direct-redirect TEASE как
обычно сопоставляет посетителя с гео-сегментом и затем 307-редиректит его прямо на назначение
кнопки этого сегмента — для смартлинк-кнопки это /r/<slug>
смарт-ссылка домена, так что лог кликов, привязка клик-id и атрибуция
выручки продолжают работать насквозь. Режим создан для размещений, где промежуточная страница
только теряет клики (например, adult-трафик из X/Twitter).
curl -X POST https://app.tease.link/api/admin/domains/links.creator.com/direct-redirect \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": true, "ab_pct": 0 }'{ "domain": "links.creator.com", "direct_redirect": true, "ab_pct": 0 }| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
enabled | bool | да | Включить или выключить режим. Выключение также сбрасывает сохранённый ab_pct в 0, чтобы повторное включение стартовало чисто (редирект всем). |
ab_pct | int | нет | Доля A/B, 0–100 — см. ниже. Опустите, чтобы оставить сохранённое значение; игнорируется, пока enabled равен false. |
Все привычные предохранители остаются включёнными:
- Цель редиректа берётся из опубликованной страницы, поэтому переключатель не требует перепубликации и вступает в силу примерно за минуту. В панели он живёт кнопкой «Прямой редирект» рядом с «Импорт», над списком кнопок.
- Цель — главная кнопка аудитории, то есть самая нижняя (её же лендинг красит основной CTA). Настройка доменная: она действует во ВСЕХ аудиториях, и каждая уводит на свою главную кнопку.
- Сегменты-редиректы и блок-сегменты по-прежнему сильнее: совпавший сегмент-редирект шлёт
свой 307 (например, в Telegram), а страна из блок-листа по-прежнему получает
403. - Боты и сканеры назначение не видят — им не отдаётся ничего, ровно как в слое клоакинга.
- In-app webview (встроенные браузеры Instagram / Facebook / TikTok) всё же получает лендинг: внутри «закрытого» webview назначение не откроется, поэтому там должен отработать клиентский «выход» со страницы.
- Если у совпавшего сегмента нет назначения для редиректа — отдаётся лендинг (fail-safe, мёртвых редиректов не бывает).
Панель показывает судьбу каждой аудитории (с 2026-07-27)
Пока режим включён, список кнопок больше не выглядит как обычная страница: у аудитории стоит метка «→ редирект» (или «→ N%» при A/B), над списком — плашка «посетители НЕ видят страницу, они уходят на …» с настоящим адресом, целевая кнопка подписана «сюда уходит редирект», а остальные погашены с подписью «посетитель не увидит». До этого панель рисовала все кнопки одинаково, и было не видно, что достаётся посетителю ровно одна.
Сменить цель можно в том же диалоге: выбранная кнопка переносится в главные. Остальные кнопки при этом остаются на месте — при A/B их видит плечо со страницей.
Цель выбирается для ОТКРЫТОЙ аудитории (2026-07-28). Флаг доменный, поэтому в диалоге рядом перечислены все остальные аудитории домена и адрес, куда уйдёт их посетитель — чтобы выбор не выглядел общим на весь домен. Хотите поменять цель другой аудитории — откройте её на рельсе и выберите кнопку там.
A/B: лендинг vs сразу-на-оффер
Тестируется здесь ровно ОДНО: страница с кнопками против прямого перехода по адресу кнопки — не «смартлинк против чего-то». Адрес может быть любым: смарт-ссылка, Telegram, инстаграм, собственный сайт; движок читает его из кнопки.
ab_pct превращает вкл/выкл в живой эксперимент на включённом домене: N% посетителей получают
прямой редирект (плечо B), остальные — обычную лендинг-воронку (плечо A). 0 = редирект всем
(без A/B); 100 — то же самое, сказанное явно. Сплит липкий на посетителя и без кук, а входной
клик несёт метку плеча, так что конверсии атрибутируются по плечу — вы измеряете, что конвертит
лучше, вместо того чтобы коммититься на 100%. Строки доменов в GET /api/admin/domains отдают
direct_redirect и direct_redirect_ab_pct.
Кнопки
Кнопки живут внутри сегмента. При управлении кнопками segment_id сегмента является path-параметром tier —
так что buttons/{domain}/{segment_id} — это «кнопки, показываемые этой аудитории».
Список кнопок сегмента
curl https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d \
-H "Authorization: Bearer $TEASE_API_KEY"{
"domain": "links.creator.com",
"tier": "s_1a2b3c4d",
"items": [
{
"button_id": "main",
"domain": "links.creator.com",
"tier": "s_1a2b3c4d",
"position": 0,
"label": "Subscribe",
"text_value": "Subscribe",
"url": "https://example.com/offer",
"icon": "heart.svg",
"hidden": false,
"match": null,
"variants": null,
"popup": null
}
]
}| Поле | Тип | Описание |
|---|---|---|
button_id | string | Стабильный id внутри сегмента. Генерируется сервером, если вы опускаете его при создании. |
position | int | Порядок внутри сегмента. |
text_value | string | Видимый текст кнопки. |
label | string | Внутренний алиас для логов/отчётов; по умолчанию равен text_value. |
url | string | Назначение, на которое указывает кнопка. |
icon | string | Имя файла ассета иконки (name.svg) — см. Иконки. |
hidden | bool | Скрыта ли кнопка на боевой странице. |
match | object[] | null | Необязательные условия отображения для конкретной кнопки (те же формы условий, что у сегментов). |
variants | object[] | null | Необязательные A/B-варианты URL для кнопки. |
popup | object | null | Всплывающая подсказка кнопки, или null, если выключена. |
Создать кнопку
curl -X POST https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text_value": "Subscribe",
"url": "https://example.com/offer",
"icon": "heart.svg"
}'Параметры
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
text_value | string | да | Видимый текст кнопки, 1–64 символа. |
url | string | да | Назначение, http(s)://, до 2048 символов. |
icon | string | да | Имя файла иконки, соответствующее [A-Za-z0-9_-].svg. |
label | string | нет | Внутренний алиас для отчётов. По умолчанию равен text_value. |
button_id | string | нет | Укажите свой id, иначе он будет сгенерирован. |
match | object | нет | Условия отображения для конкретной кнопки, { "all": [<clause>, …] }. |
variants | object | нет | Набор A/B URL, { "variants": [{ "id", "weight", "url" }, …] } (2 или больше вариантов). |
popup | object | нет | Всплывающая подсказка для кнопки. |
Редактирование и упорядочивание повторяют сегменты:
# Edit any subset of fields
curl -X PATCH https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d/main \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "text_value": "Join now" }'
# Reorder within the segment
curl -X PUT https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d/order \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "order": ["main", "secondary"] }'
# Delete
curl -X DELETE https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d/main \
-H "Authorization: Bearer $TEASE_API_KEY"A/B вкратце
Передача двух или более variants превращает кнопку в A/B-тест по URL назначения, взвешенный
по weight. TEASE берёт на себя отдачу и удержание конкретного посетителя на одном и том же варианте — вы лишь
объявляете варианты и читаете результаты в своих отчётах.
Всплывающая подсказка
Любая кнопка может нести всплывающую подсказку — небольшую карточку с фото и текстом до 160 символов, которая выезжает под кнопкой после задержки. Клик по карточке нажимает саму кнопку. Подсказка показывается не более одного раза за просмотр страницы, а посетитель, закрывший её, не увидит её снова до конца сессии.
Настройка в два шага: загрузите фото (авто-обрезка в WebP-карточку 480×360), затем задайте
объект popup на кнопке при создании или через PATCH.
# 1. Загрузить фото карточки (multipart, до 5 MB)
curl -X POST https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d/main/popup-photo \
-H "Authorization: Bearer $TEASE_API_KEY" \
-F "file=@teaser.jpg"{ "filename": "popup_9f2c1a7b3d4e.webp", "url": "/notification/links.creator.com/popup_9f2c1a7b3d4e.webp" }# 2. Привязать подсказку к кнопке
curl -X PATCH https://app.tease.link/api/admin/buttons/links.creator.com/s_1a2b3c4d/main \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"popup": {
"enabled": true,
"text": "Сегодняшний сет — скидка 50%, только 2 часа",
"delay_ms": 4000,
"photo": "popup_9f2c1a7b3d4e.webp"
}
}'Поля подсказки
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
enabled | bool | да | false (или пустой text) очищает подсказку. |
text | string | да | Текст карточки, до 160 символов. |
delay_ms | int | нет | Задержка перед выездом карточки, 500–30000 мс (по умолчанию 4000). |
photo | string | нет | Имя файла, возвращённое загрузкой popup-photo. |
Объект popup заменяет сохранённую подсказку целиком. Повторная загрузка идентичных байтов фото
идемпотентна (одинаковое содержимое → одинаковое имя файла), поэтому повторы безопасны.
Иконки
Каждая кнопка ссылается на иконку по имени файла. Библиотека иконок поставляется с ~290 встроенными иконками — бренд-марки плюс общие глифы, с поиском и категориями в пикере иконок панели — и держит рядом ваши собственные загрузки. Встроенные общие; всё, что вы загружаете или генерируете, приватно для вашего воркспейса.
# Список всего доступного (встроенные + ваши)
curl https://app.tease.link/api/admin/icons \
-H "Authorization: Bearer $TEASE_API_KEY"
# Загрузить свой SVG (санитизируется, до 1 MB)
curl -X POST https://app.tease.link/api/admin/icons \
-H "Authorization: Bearer $TEASE_API_KEY" \
-F "file=@custom.svg"Сгенерировать иконку через ИИ
Не нашли нужный глиф? POST /api/admin/icons/generate рисует новую иконку в фирменном стиле —
белая на прозрачном фоне, так что она встаёт рядом со встроенными без швов — и сохраняет её прямо
в вашу приватную библиотеку.
curl -X POST https://app.tease.link/api/admin/icons/generate \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "prompt": "бумажный самолётик", "style": "line" }'{ "filename": "gen_7c2f91d3a4b5.svg", "builtin": false, "uploaded_at": 1752537600 }| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
prompt | string | да | Концепт иконки на любом языке, до 200 символов. |
style | string | нет | line (контур штрихом, по умолчанию) или solid (залитый глиф). |
Используйте возвращённое filename как icon кнопки. Генерация ограничена 6 в минуту
(429 icon_gen_rate_limited); неудачная попытка возвращает 502 icon_ai_failed — просто
повторите с переформулированным запросом.
Баннер-уведомление
Баннер — это push-подобная карточка для каждого домена (аватар, заголовок, текст и ссылка-призыв к действию), которая появляется на странице после небольшой задержки. На домен приходится один баннер — его можно редактировать руками, а можно вести из переиспользуемой библиотеки уведомлений (две и больше включённых карточек превращают его в креативный A/B-тест).
Прочитать и отредактировать
curl https://app.tease.link/api/admin/notification/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY"{
"domain": "links.creator.com",
"enabled": true,
"avatar_filename": "av_9f.png",
"sound_filename": null,
"title": "New drop",
"body": "Tap to see today's set",
"link_text": "Open",
"target_url": "https://example.com/offer",
"delay_ms": 2500,
"translations": {},
"style": null,
"preset_id": null,
"assignment": null
}PATCH принимает любое подмножество редактируемых полей:
curl -X PATCH https://app.tease.link/api/admin/notification/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"title": "New drop",
"body": "Tap to see today’s set",
"link_text": "Open",
"target_url": "https://example.com/offer",
"delay_ms": 2500
}'Параметры
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
enabled | bool | нет | Показывается ли баннер на боевой странице. |
title | string | нет | Заголовок баннера, до 128 символов. |
body | string | нет | Текст баннера, до 256 символов. |
link_text | string | нет | Метка призыва к действию, до 64 символов. |
target_url | string | нет | Куда ведёт призыв к действию (http(s)://). Для включения обязателен только в режиме «Своя ссылка»; в смартлинк-режиме — лишь последний фолбэк. Пустое значение очищает его. |
link_mode | string | нет | Куда ведёт клик: "" (по умолчанию) = «Смартлинк» — зеркало главной кнопки сегмента; "manual" = «Своя ссылка» — target_url побеждает. См. ниже. |
delay_ms | int | нет | Задержка перед появлением баннера, 500–10000 мс. |
translations | object | нет | Переопределения публичного текста по локалям — см. переводы. |
assignment | object | нет | Какие пресеты библиотеки показывает этот баннер, { "items": [...] } — см. Библиотека уведомлений и A/B. { "items": [] } очищает назначение. |
style | object | нет | Переопределения внешнего вида баннера — см. Внешний вид. {} сбрасывает к стоковому виду. |
Куда ведёт клик
У призыва к действию баннера два режима, переключаемые link_mode:
- «Смартлинк» (
"", по умолчанию) — клик зеркалит главную кнопку сегмента, в который попал посетитель, следуя тому же tier-aware роутингу (и A/B-плечу), что и сами кнопки. URL для включения баннера в этом режиме не нужен; сохранённыйtarget_urlслужит лишь последним фолбэком, когда у сегмента нет кнопки для зеркала. - «Своя ссылка» (
"manual") — баннер ведёт ровно туда, куда вы указали:target_urlобязателен (включение без него вернёт400 notification_incomplete) и побеждает зеркало сегмента.
Внешний вид
Вид баннера настраивается независимо от его содержимого: объект style в том же PATCH несёт
ручки внешнего вида. Хранятся только заданные вами ключи; отправьте {}, чтобы сбросить баннер к
стоковому виду. Текущее значение возвращается в поле style при чтении.
curl -X PATCH https://app.tease.link/api/admin/notification/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"style": {
"theme": "glass",
"opacity": 0.9,
"radius": 18,
"avatar_shape": "circle",
"position": "top",
"accent": "#e0426e"
}
}'| Ключ | Тип | Описание |
|---|---|---|
theme | string | light, dark или glass. |
opacity | float | Прозрачность карточки, 0.3–1. |
radius | int | Радиус скругления в px, 0–32. |
avatar_shape | string | circle, rounded или square. |
position | string | top или bottom — край, из которого выезжает баннер. |
accent | string | Акцентный цвет призыва к действию, #rrggbb. |
dim | float | Затемнение-скрим под текстом баннера для читаемости, 0–0.8. Не задан = автоматический скрим 0.22 на стеклянных темах; явный 0 выключает его. |
text_size | float | Множитель размера текста баннера, 0.85–1.3. |
font | string | Шрифт баннера — тот же список шрифтов, что у font кнопок. |
Аватар и звук
Изображение аватара и необязательный звук уведомления загружаются как файлы и могут быть удалены:
# Upload an avatar (multipart)
curl -X POST https://app.tease.link/api/admin/notification/links.creator.com/avatar \
-H "Authorization: Bearer $TEASE_API_KEY" \
-F "file=@avatar.png"
# Remove the sound
curl -X DELETE https://app.tease.link/api/admin/notification/links.creator.com/sound \
-H "Authorization: Bearer $TEASE_API_KEY"Библиотека уведомлений и A/B
Вместо ручной правки каждого домена держите креативы баннера как переиспользуемые пресеты в библиотеке уведомлений и назначайте их на домены. В панели вкладка «Уведомление» — это стена карточек-пресетов с галочками: отмеченная карточка — это то, что домен показывает, две и больше галочек запускают креативный A/B-тест, а вес карточки задаёт её долю показов. Конкретный посетитель держится одного варианта (ротация sticky по подсети), так что тест остаётся чистым.
Пресет несёт креатив целиком — тексты, ссылку-призыв, задержку, переводы, плюс собственные
мастер-файлы (аватар/звук), которые хранятся в notification/_preset_<id>/ и раздаются как
/notification/_preset_<id>/<filename>. Когда пресет ставится на домен, мастера копируются в
папку домена — боевой баннер никогда не ссылается на файл, которого нет.
# Список библиотеки
curl https://app.tease.link/api/admin/library/notifications \
-H "Authorization: Bearer $TEASE_API_KEY"
# Сохранить текущий баннер домена в библиотеку — вместе с файлами
curl -X POST https://app.tease.link/api/admin/library/notifications/from-domain \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "domain": "links.creator.com", "name": "July drop" }'from-domain снимает слепок черновика баннера домена в новый пресет вместе с файлами
аватара/звука и штампует новый preset_id обратно на домен, так что карточка показывает свою
привязку к библиотеке. Ошибки: 400 name_required / 400 notification_empty (нечего сохранять),
409 preset_name_taken, 404 domain_not_found.
Назначить пресеты на домен
Объект assignment в PATCH баннера — это API за галочками. Он заменяет сохранённое назначение
целиком; { "items": [] } очищает его (назад к баннеру, отредактированному руками).
curl -X PATCH https://app.tease.link/api/admin/notification/links.creator.com \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"assignment": {
"items": [
{ "preset_id": 7, "weight": 2, "enabled": true },
{ "preset_id": 9, "weight": 1, "enabled": true },
{ "preset_id": 4, "enabled": false }
]
}
}'| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
preset_id | int | да | Id пресета из GET /api/admin/library/notifications. |
weight | int | нет | Относительная доля показов в A/B из 2+ пресетов (по умолчанию 1). Здесь пресет 7 достаётся ~2/3 посетителей. |
enabled | bool | нет | Галочка (по умолчанию true). Выключенный пункт остаётся в списке, но никогда не показывается. |
Каждый включённый пресет валидируется при сохранении: неизвестный id возвращает
404 preset_not_found, а пресет без текстов, без аватара или (в режиме «Своя ссылка») без
ссылки — 400 preset_incomplete, так
что сломанное плечо никогда молча не съест долю трафика. Первый включённый пресет штампуется в
баннер домена (тексты, файлы и preset_id), а мастер-файлы всех включённых пресетов копируются в
папку домена — назначение из одного пресета начинает показывать свой креатив сразу.
Аватары пресетов
У каждого пресета свой мастер-аватар, управляемый на самом пресете (multipart-изображение до 5 MB, центр-кроп в квадрат 192 px, WebP с content-hash именем):
# Загрузить / заменить мастер-аватар
curl -X POST https://app.tease.link/api/admin/library/notifications/7/avatar \
-H "Authorization: Bearer $TEASE_API_KEY" \
-F "file=@avatar.jpg"
# Удалить (привязанные домены тоже теряют его, и их баннеры выключаются)
curl -X DELETE https://app.tease.link/api/admin/library/notifications/7/avatar \
-H "Authorization: Bearer $TEASE_API_KEY"В панели аватар можно выбрать прямо из галереи фото или загрузить новое изображение — загруженное фото также сохраняется в галерею, так что в следующий раз оно под рукой.
Правка и применение пресетов
Правки через PATCH /api/admin/library/notifications/{preset_id} доезжают сразу: каждый домен,
чьё назначение включает этот пресет, перештамповывается, а его черновик перепекается — фикс текста
или аватара доходит до всех привязанных черновиков одним вызовом; в бой всё выходит по-прежнему
явным /publish.
POST /api/admin/library/notifications/{preset_id}/apply (тело { "domains": [...] }) штампует
пресет на домены целиком: пишет назначение из одного пресета, материализует мастер-файлы в папку
каждого домена и включает баннер только когда пресет полностью заполнен (все тексты, аватар
и — в режиме «Своя ссылка» — ссылка).
Включение следует готовности пресета. При каждой перештамповке enabled привязанных доменов
выводится из самого пресета: галочка в назначении — это намерение показывать, а баннер включается
автоматически, как только пресет становится полным (все тексты, аватар и — в режиме «Своя ссылка» — ссылка) — например, когда
в карточку наконец докинули аватар, — и честно выключается, когда пресет перестаёт быть полным.
Фон
У каждого домена есть фон, состоящий максимум из трёх частей: мобильное изображение, десктопное изображение и сплошной цвет холста, нарисованный за карточкой на десктопе. Изображения проходят через шаг загрузки и шаг редактирования; цвет холста — это один вызов.
Быстрый выбор: в карточке «ник модели» (вкладка «Кнопки») клик по аватару открывает библиотеку фонов — выберите один (→ один фон) или несколько (→ случайная ротация), не уходя из редактора кнопок. Загрузка и обрезка новых фонов остаётся во вкладке «Дизайн».
Загрузить и отредактировать изображение
bg/upload сохраняет оригинальное изображение для пары (domain, variant), где variant — это mobile или
desktop. bg/edit применяет ваше состояние дизайна обрезки/трансформации и регенерирует отдаваемые варианты.
# 1. Upload the source image for the mobile background
curl -X POST "https://app.tease.link/api/admin/bg/upload?domain=links.creator.com&variant=mobile" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-F "file=@bg-mobile.jpg"
# 2. Commit the editor design state
curl -X POST "https://app.tease.link/api/admin/bg/edit?domain=links.creator.com&variant=mobile" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "designState": { } }'const form = new FormData();
form.append('file', file); // a Blob/File of the image
await fetch(
'https://app.tease.link/api/admin/bg/upload?domain=links.creator.com&variant=mobile',
{ method: 'POST', headers: { Authorization: `Bearer ${process.env.TEASE_API_KEY}` }, body: form },
);| Query / тело | Тип | Обязательно | Описание |
|---|---|---|---|
domain | query | да | Домен, для которого задаётся фон. |
variant | query | да | mobile или desktop. |
file | multipart | да (загрузка) | Исходное изображение. |
designState | тело | да (редактирование) | Объект состояния обрезки/трансформации редактора. Передайте {}, чтобы использовать изображение как есть. |
Цвет холста
curl -X POST "https://app.tease.link/api/admin/bg/canvas-color?domain=links.creator.com" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "color": "#0d0604" }'| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
color | string | да | Hex-цвет в формате #rrggbb. |
Внешний вид кнопок
Встроенные (платформенные) дизайны дают стиль кнопок на всём лендинге — форма, заливка,
прозрачность, цвета, контраст подписи, типографика, цвета иконок, выравнивание и idle-анимация.
Он проходит тот же цикл черновик → публикация, что и всё остальное, и задаётся через
POST /api/admin/bg/ui, который несёт три независимые секции: buttons (эта),
profile и gate. В панели они живут в хабе домена
(«Дизайн» / «Лендинг»), с живым предпросмотром каждой ручки.
Объект секции заменяет сохранённую секцию целиком (отправляйте полный нужный стиль); null
сбрасывает её к стоковому виду. Хранятся только заданные вами ключи — всё опущенное сохраняет
дефолт дизайна.
curl -X POST "https://app.tease.link/api/admin/bg/ui?domain=links.creator.com" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"buttons": {
"shape": "pill",
"fill": "solid",
"opacity": 0.95,
"color": "#e0426e",
"text": "auto",
"animation": "breathe",
"anim_speed": "slow",
"font": "unbounded",
"align": "icon_left"
}
}'
# Назад к стоковому виду
curl -X POST "https://app.tease.link/api/admin/bg/ui?domain=links.creator.com" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "buttons": null }'| Ключ | Тип | Описание |
|---|---|---|
shape | string | rounded, pill, square или sharp. |
fill | string | glass, solid, outline, soft_shadow или hard_shadow. |
opacity | float | Прозрачность фона кнопки, 0.05–1. |
color | string | Цвет кнопки, #rrggbb. Пустая строка возвращает к дефолту. |
shadow_color | string | Цвет тени для теневых заливок, #rrggbb. |
text | string | Режим подписи: auto (подбор под цвет кнопки), dark или light. |
animation | string | none, pulse, breathe, float, shake, glow, shine, wobble или heartbeat. |
anim_speed | string | slow, normal или fast. |
font | string | Шрифт подписи: wix (по умолчанию), gilroy, tiktok, satoshi, nunito, onest, clashdisplay, bebas, unbounded, prata, pacifico или greatvibes — см. Шрифты. |
text_size | float | Множитель размера подписи, 0.7–1.5. |
text_color | string | Свой цвет надписей, #rrggbb — точный hex побеждает режим text. Пусто = авто (светлый/тёмный подбирается по светлоте поверхности). |
icon_color | string | Цвет глифа иконки, #rrggbb. Пустая строка возвращает стоковый белый глиф. |
icon_bg | string | Цвет кружка-подложки под иконкой, #rrggbb, или none — без кружка. Пустая строка возвращает стоковый чёрный кружок. |
align | string | center (иконка + подпись по центру одной группой), icon_left (иконка прижата к левому краю, подпись по центру) или left (вся строка влево). |
fills | array of string | До 6 стилей заливки (тот же список, что у fill); при 2+ значениях кнопка циклически перебирает их вместо одной плоской заливки. Меньше 2 значений — сворачивается обратно в обычный fill. |
hover | string | Эффект при наведении курсора на десктопе: lift, none, ink, glow, shine, tilt, press или border. |
new_tab | bool | Открывать ссылку каждой кнопки в новой вкладке вместо перехода — некоторые рекламные сети это требуют. |
reveal_delay | float | Секунды перед появлением всего ряда кнопок при загрузке, 0–10 (0 = мгновенно). Для точечных триггеров по скроллу/задержке/касанию/уходу на отдельные элементы см. Правила появления. |
width | int | Фиксированная ширина кнопки в px, 160–360. |
pad_y | int | Вертикальный отступ в px, 6–28. |
Полный рабочий пример — Style every button on the landing page; свободный холст, стопка тизеров, закреплённая панель, споттлайт и правила появления, которые живут рядом с этой секцией — на странице Landing-page builder.
Шрифты
Один и тот же брендовый пак из двенадцати начертаний питает каждую типографическую ручку
страницы — подписи кнопок (buttons.font), карточку профиля (name_font / bio_font) и
баннер-уведомление (style.font):
| Id | Начертание | Заметки |
|---|---|---|
wix | Wix Madefor Display | Брендовый дефолт — то, что вы получаете, когда шрифт не задан. |
gilroy | Gilroy | Премиум-гротеск «в стиле OnlyFans» (сам логотип OnlyFans — кастомный леттеринг; это ближайший по виду шрифт). |
tiktok | TikTok Sans | Настоящий фирменный шрифт TikTok (выпущен под OFL). |
satoshi | Satoshi | Современный гротеск. Только латиница. |
nunito | Nunito | Округлый дружелюбный гротеск. |
onest | Onest | Чистый геометрический гротеск. |
clashdisplay | Clash Display | Фэшн-дисплейное начертание. Только латиница. |
bebas | Bebas Neue | Высокие узкие капсы. Только латиница. |
unbounded | Unbounded | Широкий крипто-модерн дисплей. |
prata | Prata | Элегантная антиква. |
pacifico | Pacifico | Жирный кистевой скрипт. |
greatvibes | Great Vibes | Парадный каллиграфический скрипт. |
У латиница-only начертаний (satoshi, clashdisplay, bebas) нет кириллических глифов —
кириллический текст в них автоматически падает в брендовый дефолт, так что русская подпись никогда
не отрисуется «тофу». Id из снятого пака v1 продолжают читаться: они просто рендерятся дефолтом.
Смена font перерисовывает на сервере каждую подпись кнопок домена в новом начертании (подписи —
заранее запечённые SVG); ответ возвращает их число в relabeled. Все шрифты самохостятся под
свободными лицензиями и отдаются same-origin с вашего домена (/fonts/lf_<id>.woff2) — страница
не делает ни одного стороннего запроса за шрифтами.
Только платформенные дизайны
Стиль применяется, пока домен использует встроенный дизайн. Загруженный кастомный HTML-дизайн владеет своим видом и никогда не наследует эти настройки — но ваша настройка сохраняется, так что возврат к платформенному дизайну её восстанавливает.
Бейдж бесплатного тарифа
Лендинги воркспейсов на бесплатном тарифе показывают маленький бейдж «tease.link» под кнопками (в том числе на кастомных дизайнах). Апгрейд убирает его автоматически — настраивать нечего.
Карточка профиля
Тот же endpoint bg/ui настраивает карточку профиля над кнопками — шрифт и размер ника,
строку статуса «Active now • Responds in 5 mins» и необязательное био со своими шрифтом и
размером — через вторую секцию, profile. Только платформенные дизайны, тот же цикл черновик → публикация, та же замена секции
целиком: отправляйте полную нужную секцию, либо { "profile": null } для сброса к стоковой карточке.
curl -X POST "https://app.tease.link/api/admin/bg/ui?domain=links.creator.com" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"profile": {
"name_font": "unbounded",
"name_size": 1.2,
"status_text": "Online now",
"bio": "18+ • daily drops",
"bio_font": "nunito",
"bio_size": 0.9
}
}'| Ключ | Тип | Описание |
|---|---|---|
name_font | string | Шрифт ника — тот же список шрифтов, что у font кнопок. |
name_size | float | Множитель размера ника, 0.7–1.6. |
status | bool | Показывать ли строку статуса. false скрывает её; опущено = показывается. |
status_text | string | Свой текст строки статуса, до 48 символов. Пусто возвращает стоковый. |
bio | string | Короткое био под ником/статусом, до 160 символов. Пусто убирает его. |
bio_font | string | Шрифт био — тот же список шрифтов. Опущено = брендовый дефолт. |
bio_size | float | Множитель размера био, 0.7–1.6 (1 = сток). |
Контентный гейт 18+
Тот же endpoint bg/ui несёт необязательный гейт 18+ для чувствительного контента — шаг
подтверждения перед страницей: либо полноэкранная обложка (опционально с размытием страницы за
ней), либо компактный лист сверху. Посетитель подтверждает один раз на браузер, и его больше не
спрашивают. Только платформенные дизайны, тот же цикл черновик → публикация.
curl -X POST "https://app.tease.link/api/admin/bg/ui?domain=links.creator.com" \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"gate": {
"enabled": true,
"mode": "cover",
"blur": true,
"title": "Только для взрослых",
"text": "Эта страница содержит контент для взрослых.",
"ok": "Мне есть 18",
"leave": "Уйти",
"leave_url": "https://google.com"
}
}'| Ключ | Тип | Описание |
|---|---|---|
enabled | bool | Показывается ли гейт. |
mode | string | cover — полноэкранное подтверждение; drop — лист сверху. |
title / text | string | Свой текст (64 / 300 символов). Опустите для стокового. |
ok / leave | string | Подписи кнопок (по 32 символа). |
leave_url | string | Куда кнопка «уйти» отправляет отказавшихся. Пусто = нейтральный дефолт. |
blur | bool | Размыть страницу за гейтом в режиме cover. |
Отправьте { "gate": null }, чтобы убрать гейт полностью.
Большинству креаторов это не нужно
Гейт — для людей, дополнительный слой консерватизма для строгих источников трафика. Боты, скраперы и in-app сканеры ссылок уже обработаны: клоакинг держит ваши контент-кнопки невидимыми для них, не беспокоя реальных фанатов.
Десктоп во весь экран, свободный холст, стопка, закреплённая панель и правила появления
bg/ui несёт ещё несколько секций помимо buttons/profile/gate — полные разборы живут в
Landing-page builder (на английском, это интерфейсный
раздел), здесь — сводка, чтобы вся поверхность bg/ui была в одном месте:
| Секция | Что делает | Полный гайд |
|---|---|---|
desktop | Раскладка на весь монитор на широких экранах вместо карточки-телефона. mode (phone/wide), align, width (280–560), dim (0–0.7), blur. | Enable full-screen desktop mode |
layout | mode: "free" переключает колонку кнопок на свободный холст; pos расставляет каждую кнопку/объект по id как {x, y, w, h}. | Place elements freely on a canvas |
objects | Дополнительные элементы холста — items[] типов text/image/video/icon/shape/teaser/badge, до 40 штук. | Place elements freely on a canvas |
stack | Свайпаемая/закреплённая стопка до 8 закрытых тизер-карточек. | Build a teaser card stack/carousel |
sticky | Панель, остающаяся видимой при скролле, со своим стилем CTA-кнопки. | Add a sticky call-to-action bar |
appear | Правила показа по элементам — реакция на скролл/задержку/касание/уход вместо мгновенного показа, плюс отложенное появление фона. | Control when an element or background appears |
exit / timer | Попап при уходе посетителя и/или таймер срочности. | Add an exit-intent popup and/or an urgency timer |
Спотлайт — целый дизайн, а не секция bg/ui
POST /api/admin/bg/design {"design": "spotlight"} переключает страницу на второй встроенный
дизайн (рядом с classic), который держит фото-героя зафиксированным за кнопками вместо
скроллящейся колонки. Своя секция spotlight в bg/ui (blur 0–40, focus_x/focus_y 0–100,
zoom 100–300) настраивает точку фокуса, зум и размытие снизу у этого фото. Свободный холст
(layout.mode: "free" + objects) на дизайне Spotlight недоступен.
Языки и авто-перевод
Сегменты несут необязательную цель lang, а баннер-уведомление несёт карту translations,
так что публичный текст может авто-переводиться по локалям. Объект translations индексируется по коду
языка и хранит только публичные текстовые поля:
{
"translations": {
"es": { "title": "Nuevo drop", "body": "Toca para ver el set de hoy", "link_text": "Abrir" },
"fr": { "title": "Nouveau drop", "link_text": "Ouvrir" }
}
}Поддерживаемые коды включают en, ru, pt, es, de, fr, it, nl, pl, tr, ar, hi,
id, ja, ko, zh. Назначение призыва к действию никогда не является частью перевода — только
видимые title, body и link_text.
QR-коды
Каждый домен может раздавать печатные QR-коды — флаер, наклейку, визитку, — которые ведут прямо на лендинг и считаются как любой другой источник трафика, живут вне цикла черновик/публикация. Создание, дизайн, скачивание, чтение воронки кода и переименование или отключение без потери уже напечатанного — см. QR codes (страница на английском, это техническая справка API).
Черновик → предпросмотр → публикация
Всё вышеперечисленное пишется в черновик. Ничто не идёт в бой, пока вы не опубликуете. Рекомендуемый цикл:
Осмотрите состояние черновика и опубликованного
GET /api/admin/config возвращает оба снимка плюс то, какие домены «грязные»:
curl https://app.tease.link/api/admin/config \
-H "Authorization: Bearer $TEASE_API_KEY"{
"is_dirty": true,
"dirty_domains": ["links.creator.com"],
"draft": { "updated_at": 1751280600, "domains": {}, "segments": {}, "notifications": {}, "backgrounds": {} },
"published": { "updated_at": 1751280000, "domains": {}, "segments": {}, "notifications": {}, "backgrounds": {} }
}| Поле | Тип | Описание |
|---|---|---|
is_dirty | bool | Отличается ли черновик какого-либо домена от его опубликованной страницы. |
dirty_domains | string[] | Хосты с неопубликованными изменениями. |
draft / published | object | Матрицы кнопок, сегментов, уведомлений и фонов по доменам для каждого состояния. |
Просмотрите боевую аудиторию
Запросите подписанный токен предпросмотра, затем откройте с ним страницу предпросмотра. Вы можете симулировать точную аудиторию — страну, устройство, ОС, час и язык — так что увидите, что увидел бы мобильный посетитель из США в 21:00, ничего не меняя в бою.
В панели предпросмотр лендинга управляется одним селектором «Аудитория»: выберите сегмент
(каждый вариант показывает флаги стран и число кнопок), и предпросмотр отрисует эту аудиторию.
Под капотом селектор закрепляет сегмент через force_segment, так что даже дефолтный catch-all
без стран предпросматривается точно. Он
двусторонне синхронизирован с рейкой сегментов, а точечные оверрайды страны / ОС / часа / языка
живут под «ещё…».
curl "https://app.tease.link/api/admin/preview-token?domain=links.creator.com&force_country=US&force_device=mobile" \
-H "Authorization: Bearer $TEASE_API_KEY"{
"token": "…",
"public_url": "https://links.creator.com",
"frame_path": "/preview-frame/"
}| Query | Тип | Описание |
|---|---|---|
domain | string | Домен для предпросмотра. |
force_country | string | Симулировать страну (ISO alpha-2, верхний регистр). |
force_device | string | mobile или desktop. |
force_os | string | ios, android, windows, macos или other. |
force_hour | int | Симулировать час суток, 0–23. |
force_lang | string | Симулировать 2-буквенный язык. |
force_segment | string | Отрисовать ровно этот сегмент (по segment_id), минуя гео-классификатор. Неизвестные id игнорируются; блок-сегмент по-прежнему показывает свой 403. |
Возвращаемый token короткоживущий и авторизует только предпросмотр вашего собственного черновика. Откройте
public_url, соединённый с frame_path, передав токен, чтобы отрендерить симулируемую страницу.
Только для владельца
preview-token ограничен владельцем аккаунта.
Опубликуйте (или отмените)
Когда предпросмотр выглядит правильно, опубликуйте черновик на боевую страницу. Отмена выбрасывает черновик и восстанавливает его из опубликованной страницы — ваш единственный глобальный откат.
Публикация и отмена
POST /api/admin/publish атомарно копирует черновик на боевую страницу. Без тела он публикует
каждый грязный домен; передайте массив domains, чтобы опубликовать только некоторые.
# Publish everything that changed
curl -X POST https://app.tease.link/api/admin/publish \
-H "Authorization: Bearer $TEASE_API_KEY"
# Publish only one domain
curl -X POST https://app.tease.link/api/admin/publish \
-H "Authorization: Bearer $TEASE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "domains": ["links.creator.com"] }'await fetch('https://app.tease.link/api/admin/publish', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TEASE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ domains: ['links.creator.com'] }),
});requests.post(
"https://app.tease.link/api/admin/publish",
headers={"Authorization": f"Bearer {os.environ['TEASE_API_KEY']}"},
json={"domains": ["links.creator.com"]},
)| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
domains | string[] | нет | Хосты для публикации. Опустите (или не отправляйте тело), чтобы опубликовать все грязные домены. Явный пустой список отклоняется. |
{ "ok": true, "bg_files_by_domain": {}, "domains": ["links.creator.com"] }Публикация без изменений возвращает 400 nothing_to_publish. POST /api/admin/discard принимает
такой же необязательный выбор domains и восстанавливает черновик из опубликованного; если откатывать нечего,
он возвращает { "ok": true, "noop": true }.
discard разрушителен для ваших правок в черновике — он заменяет черновик тем, что сейчас в
бою. Ваша опубликованная страница не затрагивается.
Лента аудита
Каждое изменение выше журналируется. GET /api/admin/audit возвращает самые свежие записи (новые
первыми), полезно для ленты активности или журнала изменений.
curl "https://app.tease.link/api/admin/audit?limit=50" \
-H "Authorization: Bearer $TEASE_API_KEY"{
"items": [
{
"id": 9012,
"ts": 1751280600,
"actor": "owner",
"action": "publish",
"payload": "{\"tiers_updated\": true}"
}
]
}| Поле | Тип | Описание |
|---|---|---|
limit | query | Количество возвращаемых записей, 1–500 (по умолчанию 100). |
id | int | Монотонный id записи. |
ts | int | Unix-метка времени. |
actor | string | Кто внёс изменение. |
action | string | Тип изменения (например, segment_create, publish). |
payload | string | null | JSON-строка с деталями, специфичными для действия. |
FAQ
Дальнейшие шаги
Подключение аккаунта
Подключите свой OnlyFans к TEASE двумя способами — окно нашего браузера или расширение, — чтобы движок мог читать данные и отчитываться по выручке. Ban-safe: выделенный прокси и устройство на весь срок сессии.
Конструктор лендинга
Простыми словами — как настроить фон, полноэкранный режим на ПК, медиа-плитки, видео и удержание посетителя. Всё редактируется в панели как черновик и включается кнопкой «Опубликовать».