Документация API livesurf.ru
Авторизуйтесь или зарегистрируйтесь, чтобы получить API-ключ.
Войти или зарегистрироватьсяLiveSurf Client API
Дата обновления документации: 2026-05-28
Что это
REST API LiveSurf для управления аккаунтом, группами, страницами, источниками трафика и получения статистики.
- Base URL:
https://api.livesurf.ru - Формат: JSON
- Авторизация: заголовок
Authorization: <API_KEY> - Rate limit: не более
10запросов в секунду
Быстрый старт
Обязательные заголовки
Authorization: <API_KEY>
Accept: application/json
Content-Type: application/json
Пример GET
curl -sS "https://api.livesurf.ru/user/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json"
Пример POST
curl -sS -X POST "https://api.livesurf.ru/user/manualmode/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json"
Пример PATCH
curl -sS -X PATCH "https://api.livesurf.ru/group/12345/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"name":"Updated group"}'
Пример PUT
curl -sS -X PUT "https://api.livesurf.ru/group/12345/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"name":"Full group update", "hour_limit": 100, "day_limit": 5000}'
Карта API
Справочники и лимиты
GET /categories/— список возможных категорийGET /countries/— список возможных странGET /languages/— список доступных языковGET /limits/— лимиты текущего аккаунта и справочные лимиты по типам аккаунтов
Источники
GET /sources/search/— список поисковых системGET /sources/ad/— список рекламных площадокGET /sources/messengers/— список мессенджеровGET /sources/social/— список социальных сетейGET /sources/neural/— список источников нейросетейGET /sources/recommender/— список источников рекомендательных систем
Пользователь
GET /user/— получение информации о пользователеPOST /user/automode/— включение режима АРК (автоматическая рекламная кампания)POST /user/manualmode/— включение ручного режима работы
Группы
GET /group/all/— информация о добавленных группахGET /group/{group_id}/— информация о конкретной группеPATCH /group/{group_id}/— частичное изменение настроек группыPUT /group/{group_id}/— полное обновление настроек группыDELETE /group/{group_id}/— удаление группыPOST /group/create/— создание новой группыPOST /group/{group_id}/clone/— клонирование группыPOST /group/{group_id}/add_credits/— зачисление кредитов посещений на счёт группы в ручном режиме работыPOST /group/{group_id}/refund_credits/— возврат всех кредитов с проекта на основной баланс в ручном режимеPOST /group/{group_id}/reorder/— изменение порядка страниц в группе
Страницы
GET /page/{page_id}/— информация о конкретной страницеPATCH /page/{page_id}/— частичное изменение настроек страницыPUT /page/{page_id}/— полное обновление настроек страницыDELETE /page/{page_id}/— удаление страницыPOST /page/create/— создание новой страницыPOST /page/{page_id}/clone/— клонирование страницыPOST /page/{page_id}/up/— перемещение страницы на позицию вверхPOST /page/{page_id}/down/— перемещение страницы на позицию внизPOST /page/{page_id}/start/— запуск страницы в работуPOST /page/{page_id}/stop/— остановка работы страницыGET /pages-compiled-stats/— статистика показа страницы
Стандарт ошибок
Чаще всего API возвращает ошибки в формате:
{
"errors": {
"field": ["message"]
}
}
или:
{
"errors": {
"detail": "message"
}
}
Лимиты и стоимость
GET /limits/
Назначение: вернуть лимиты и стоимость (pricing).
Параметры: нет.
Ответ содержит 4 блока:
general.timezone— таймзона, в которой работает API.limits— справочные лимиты по типам аккаунтов: Минимум (account_type_id: 0,min), Стандарт (1,pro), Премиум (2,vip).user.limits— фактические лимиты текущего пользователя с учетом индивидуальных расширений.pricing— стоимость посещения по showtime + модификаторы.
Важно: для валидации UI и запросов используйте user.limits.
Ключевые поля user.limits
min_showtime/max_showtime— диапазон каждого значенияpage.showtime(fromиtoвалидируются отдельно).min_daylimit/max_daylimit— диапазонgroup.day_limit; приmin_daylimit = 0разрешенday_limit = 0.min_hourlimit/max_hourlimit— диапазонgroup.hour_limit; приmin_hourlimit = 0разрешенhour_limit = 0.min_imp/max_imp— диапазон каждого значенияgroup.interval; приmin_imp = 0возможно отключение.max_keywords— максимум элементовsources.keywords.settings.list.max_backlinks— максимум элементовsources.backlinks.settings.list.max_selectors— максимум элементовbehavior.settings.clicks.listв режимеclicks.max_active_pages— число слотов одновременного запуска страниц.max_alternate_urls— число дополнительных URL; общий максимум URL на страницу:1 + max_alternate_urls.max_total_pages— максимум страниц на аккаунт.
Пример ответа:
{
"general": {
"timezone": "Europe/Moscow"
},
"limits": [
{
"account_type_id": 0,
"account_type": "min",
"min_showtime": 15,
"max_showtime": 45,
"min_daylimit": 0,
"max_daylimit": 200,
"min_hourlimit": 0,
"max_hourlimit": 50,
"min_imp": 0,
"max_imp": 10800,
"max_keywords": 50,
"max_backlinks": 50,
"max_selectors": 2,
"max_active_pages": 1,
"max_alternate_urls": 0,
"max_total_pages": 100
},
{
"account_type_id": 1,
"account_type": "pro",
"min_showtime": 15,
"max_showtime": 300,
"min_daylimit": 0,
"max_daylimit": 1000,
"min_hourlimit": 0,
"max_hourlimit": 200,
"min_imp": 0,
"max_imp": 10800,
"max_keywords": 100,
"max_backlinks": 100,
"max_selectors": 5,
"max_active_pages": 12,
"max_alternate_urls": 5,
"max_total_pages": 200
},
{
"account_type_id": 2,
"account_type": "vip",
"min_showtime": 15,
"max_showtime": 900,
"min_daylimit": 0,
"max_daylimit": 2000,
"min_hourlimit": 0,
"max_hourlimit": 501,
"min_imp": 0,
"max_imp": 10800,
"max_keywords": 300,
"max_backlinks": 300,
"max_selectors": 10,
"max_active_pages": 24,
"max_alternate_urls": 10,
"max_total_pages": 104
}
],
"pricing": {
"showtime_price": {
"15": 0.5,
"900": 499
},
"modifiers": [
{
"key": "geotargeting",
"type": "percentage",
"value": "0.30",
"description": "Геотаргетинг включён: +30%",
"enabled": true
},
{
"key": "low_pf",
"type": "percentage",
"value": "-0.70",
"description": "Трафик с низкими поведенческими факторами: -70%",
"enabled": true
}
]
},
"user": {
"limits": {
"account_type_id": 2,
"account_type": "vip",
"min_showtime": 15,
"max_showtime": 900,
"min_daylimit": 0,
"max_daylimit": 2000,
"min_hourlimit": 0,
"max_hourlimit": 501,
"min_imp": 0,
"max_imp": 10800,
"max_keywords": 300,
"max_backlinks": 300,
"max_selectors": 10,
"max_active_pages": 24,
"max_alternate_urls": 10,
"max_total_pages": 104
}
}
}
Справочники
GET /categories/
Назначение: категории для group.category.
Параметры: нет.
Пример ответа:
[
{
"id": 1,
"name": "Интернет, Компьютеры",
"parent": 0,
"active": true
}
]
GET /countries/
Назначение: страны для group.geo.
Параметры: нет.
Пример ответа:
[
{
"id": 1,
"country": "RU",
"region": "",
"city": "",
"name": "Россия"
}
]
GET /languages/
Назначение: языки для group.language.
Параметры: нет.
Пример ответа:
[
{
"id": 2,
"name": "Russian",
"translate_name": "Русский"
}
]
Источники
GET /sources/search/
Назначение: список поисковых систем для sources.keywords.settings.search_engines.
Параметры: нет.
Поля элемента ответа:
id— ID источника (используется как ключ вsources.keywords.settings.search_engines).name— название источника.default— вес по умолчанию (строка с числом).payload— объект с данными источника:iso(код страны/региона, например "RU", "BY", "KZ", "global"),str_id(строковый идентификатор, например "mail_ru", "ya_by", "rambler_ru").enable— доступность источника.
Пример ответа:
[
{
"id": 11,
"name": "Mail.RU",
"default": "0.8",
"payload": {
"iso": "RU",
"str_id": "mail_ru"
},
"enable": true
}
]
GET /sources/ad/
Назначение: список рекламных площадок для sources.adsystems.settings.
Параметры: нет.
Поля элемента ответа: name, default, payload, enable. В payload: iso (код страны/региона, например "RU", "global"), fullName (отображаемое название, например "Facebook", "Google AdSense", "Kavanga").
Пример ответа:
[
{
"name": "facebook",
"default": true,
"payload": {
"iso": "global",
"fullName": "Facebook"
},
"enable": true
}
]
GET /sources/messengers/
Назначение: список мессенджеров для sources.messengers.settings.
Параметры: нет.
Поля элемента ответа: name, default, payload, enable. В payload: iso (код страны/региона, например "global", "UA"), fullName (отображаемое название, например "Slack", "Viber", "WhatsApp").
Пример ответа:
[
{
"name": "telegram",
"default": true,
"payload": {
"iso": "global",
"fullName": "Telegram"
},
"enable": true
}
]
GET /sources/social/
Назначение: список соцсетей для sources.socialanalytics.settings.
Параметры: нет.
Поля элемента ответа: name, default, payload, enable. В payload: iso (код страны/региона, например "global", "RU", "CN"), fullName (отображаемое название, например "Instagram", "Pinterest", "VK", "Weibo", "Douyin", "Reddit").
Пример ответа:
[
{
"name": "pinterest",
"default": false,
"payload": {
"iso": "global",
"fullName": "Pinterest"
},
"enable": true
}
]
GET /sources/neural/
Назначение: список источников нейросетей для sources.neurals.settings.
Параметры: нет.
Поля элемента ответа: name, default, payload, enable. В payload: iso (код страны/региона, например "US"), fullName (отображаемое название, например "Poe", "Microsoft Edge Services", "Exa", "QuillBot", "Reka AI").
Пример ответа:
[
{
"name": "poe",
"default": false,
"payload": {
"iso": "US",
"fullName": "Poe"
},
"enable": true
}
]
GET /sources/recommender/
Назначение: список источников рекомендательных систем для sources.recommenders.settings.
Параметры: нет.
Поля элемента ответа: name, default, payload, enable. В payload: iso (код страны/региона, например "global", "RU", "CN"), fullName (отображаемое название, например "Opera Personal News", "Мир тесен", "Toutiao", "Дзен").
Пример ответа:
[
{
"name": "opera_personal_news",
"default": false,
"payload": {
"iso": "global",
"fullName": "Opera Personal News"
},
"enable": true
}
]
Пользователь
GET /user/
Назначение: получить параметры пользователя и текущий режим работы.
Параметры: нет.
Ключевые поля ответа:
credits— текущий баланс кредитов.workmode— режим работы (0ручной,1автоматический).type— ID типа аккаунта (справочно; для валидации лимитов использоватьGET /limits/ -> user.limits).experience— опыт пользователя.token— токен пользователя.is_active— активность аккаунта.
Пример ответа:
{
"credits": "170491620.33332",
"workmode": 0,
"type": 2,
"experience": 72009,
"token": "...",
"is_active": true
}
POST /user/automode/
Назначение: включить автоматический режим (АРК).
Параметры: нет.
Пример ответа:
{"status": 1}
POST /user/manualmode/
Назначение: включить ручной режим.
Параметры: нет.
Пример ответа:
{"status": 1}
Группы
GET /group/all/
Назначение: список всех групп аккаунта с полной конфигурацией и вложенными страницами.
Параметры: нет.
Пример ответа:
[
{
"id": 123,
"name": "My group",
"hour_limit": 50,
"day_limit": 1000,
"interval": [30, 180],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"autocalc_visits": {
"enabled": false,
"lower_at_night": false,
"lower_at_week": false
},
"use_profiles": true,
"retention": true,
"description": "",
"timezone": "Europe/Moscow",
"category": 1,
"language": 2,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"schedules": [],
"low_pf": {"enabled": false, "ratio": 30},
"sources": {
"keywords": {"value": 50, "enabled": true, "settings": {"list": ["пример фразы"], "search_engines": {"1": 1}}},
"adsystems": {"value": 20, "enabled": true, "settings": ["B2BContext"]},
"backlinks": {"value": 10, "enabled": true, "settings": {"list": ["https://example.com"]}},
"messengers": {"value": 5, "enabled": true, "settings": ["telegram"]},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {"value": 5, "enabled": true, "settings": ["pinterest"]},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
},
"pages": [
{
"id": 999,
"state": 1,
"position": 0,
"url": ["https://example.com/"],
"showtime": [15, 30],
"break_chain": 0,
"adult": false,
"group_id": 123,
"behavior": {"mode": "disabled", "settings": {"reading_up": false, "clicks": {"list": []}}}
}
],
"credits": 0
}
]
GET /group/{group_id}/
Назначение: полная конфигурация конкретной группы.
Параметры URL:
group_id— ID группы.
Примечание: список group_id можно получить через GET /group/all/.
Пример ответа:
{
"id": 123,
"name": "My group",
"hour_limit": 50,
"day_limit": 1000,
"interval": [30, 180],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"stopping_hours": [1, 2, 3],
"autocalc_visits": {
"enabled": false,
"lower_at_night": false,
"lower_at_week": false
},
"use_profiles": true,
"retention": true,
"description": "",
"timezone": "Europe/Moscow",
"category": 1,
"language": 2,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"schedules": [],
"low_pf": {"enabled": false, "ratio": 30},
"sources": {
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["пример фразы"],
"search_engines": {"1": 1}
}
},
"adsystems": {"value": 20, "enabled": true, "settings": ["B2BContext"]},
"backlinks": {"value": 10, "enabled": true, "settings": {"list": ["https://example.com"]}},
"messengers": {"value": 5, "enabled": true, "settings": ["telegram"]},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {"value": 5, "enabled": true, "settings": ["pinterest"]},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
},
"pages": [
{
"id": 999,
"state": 1,
"position": 0,
"url": ["https://example.com/"],
"showtime": [15, 30],
"break_chain": 0,
"adult": false,
"group_id": 123,
"behavior": {
"mode": "neural",
"settings": {"reading_up": true, "clicks": {"list": ["a", ".link"]}}
}
}
],
"credits": 0
}
PATCH /group/{group_id}/
Назначение: частичное обновление группы. Обновляются только переданные поля, остальные поля группы остаются без изменений. Валидация применяется только к переданным полям.
Параметры URL:
group_id— ID группы.
Тело запроса: любой поднабор полей ниже.
Основные поля:
name(string) — название группы, до 255 символов.hour_limit(int) — часовой лимит в диапазонеmin_hourlimit..max_hourlimitиз/limits/; еслиmin_hourlimit = 0, допускается0.day_limit(int) — суточный лимит в диапазонеmin_daylimit..max_daylimit; еслиmin_daylimit = 0, допускается0.interval(array[int,int]) — интервал между показами[from, to], каждое значение ограниченоmin_imp..max_imp.uniq_ip(int) — уникальность IP в часах (0выключено, максимум168).moby_ratio(int) — доля mobile трафика0..100.geo(array[int]) — список стран (GET /countries/).autocalc_visits(object) — авторасчет лимитов:enabled(bool)lower_at_night(bool) — снижать посещения в ночное время до 10% относительно часового пояса группыlower_at_week(bool)
use_profiles(bool) — профили посетителей с активной поисковой историей, для улучшения поведенческих факторов.retention(bool) — удержание.description(string) — описание до 100 символов.timezone(string) — TZID, напримерEurope/Moscow.stopping_hours(array[int]) — часы недели,1..168.category(int) — ID категории (GET /categories/).language(int) — ID языка (GET /languages/).bookmarks(array[int,int]) — диапазон переходов из закладок.autolimit(array[int,int]) — диапазон автоизменения суточного лимита (-500..500).low_pf(object) — трафик с низкими ПФ:enabled(bool)ratio(int)
schedules(array) — расписание (VIP): элементы вида[state, "dd.mm.yyyy HH:MM"]; state:0— пауза,1— возобновить показ. Пример:[[1, "07.02.2026 14:00"], [0, "08.02.2026 10:00"]].- Таймзона: дата интерпретируется в таймзоне группы (поле
timezone). Еслиtimezoneпередан в том же запросе — используется он, иначе берётся уже сохранённый у группы, иначеEurope/Moscow. Ответ API форматирует дату в той же таймзоне группы. - Гранулярность — час: минуты входных данных округляются вниз до начала часа (
14:37сохранится и сработает как14:00).
- Таймзона: дата интерпретируется в таймзоне группы (поле
sources(object) — настройки источников посещений.
Структура sources:
keywords:value(int),enabled(bool)settings.list(array[string]) — максимумmax_keywordssettings.search_engines(map[string,float]) — ключи: id изGET /sources/search/; значения: float от 0 до 1 (соотношение использования поисковой системы)
adsystems:value(int),enabled(bool)settings(array[string]) — значения изGET /sources/ad/
backlinks:value(int),enabled(bool)settings.list(array[string]) — максимумmax_backlinks
messengers:value(int),enabled(bool)settings(array[string]) — изGET /sources/messengers/
clickunders:value(int),enabled(bool)emailanalytics:value(int),enabled(bool)socialanalytics:value(int),enabled(bool)settings(array[string]) — изGET /sources/social/
neurals:value(int),enabled(bool)settings(array[string]) — изGET /sources/neural/
recommenders:value(int),enabled(bool)settings(array[string]) — изGET /sources/recommender/
qrcodes:value(int),enabled(bool)
Примеры структур по источникам
keywords (переходы из поисковых систем):
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["пример фразы", "другая фраза"],
"search_engines": {"1": 0.7, "2": 0.3}
}
}
adsystems (переходы из рекламных систем):
"adsystems": {
"value": 20,
"enabled": true,
"settings": ["B2BContext", "adfox"]
}
backlinks (переходы по прямым ссылкам):
"backlinks": {
"value": 10,
"enabled": true,
"settings": {
"list": ["https://example.com", "https://example.com/page"]
}
}
messengers (переходы из мессенджеров):
"messengers": {
"value": 5,
"enabled": true,
"settings": ["telegram", "whatsapp"]
}
clickunders (переходы с кликандеров):
"clickunders": {
"value": 5,
"enabled": true
}
emailanalytics (переходы с почтовых рассылок):
"emailanalytics": {
"value": 5,
"enabled": true
}
socialanalytics (переходы из социальных сетей):
"socialanalytics": {
"value": 5,
"enabled": true,
"settings": ["pinterest", "instagram"]
}
neurals (переходы из нейросетей):
"neurals": {
"value": 5,
"enabled": true,
"settings": ["chatgpt", "poe"]
}
recommenders (переходы из рекомендательных систем):
"recommenders": {
"value": 5,
"enabled": true,
"settings": ["dzen", "opera_personal_news"]
}
qrcodes (переходы через QR-коды):
"qrcodes": {
"value": 5,
"enabled": true
}
Пример запроса:
curl -sS -X PATCH "https://api.livesurf.ru/group/123/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{
"hour_limit": 100,
"day_limit": 10000,
"interval": [60, 300],
"autocalc_visits": {"enabled": true, "lower_at_night": true, "lower_at_week": false},
"sources": {
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["Поисковая фраза"],
"search_engines": {"1": 1}
}
},
"adsystems": {
"value": 50,
"enabled": true,
"settings": ["B2BContext"]
}
}
}'
Пример ответа: структура как у GET /group/{group_id}/ (все поля группы).
Пример полной конфигурации (тело для PATCH или фрагмент для PUT):
{
"name": "My group",
"hour_limit": 100,
"day_limit": 10000,
"interval": [60, 300],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"timezone": "Europe/Moscow",
"stopping_hours": [1, 2, 4, 5, 7, 9],
"autocalc_visits": {
"enabled": true,
"lower_at_night": true,
"lower_at_week": false
},
"use_profiles": true,
"retention": true,
"description": "",
"category": 1,
"language": 1,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"low_pf": {"enabled": false, "ratio": 30},
"schedules": [
[1, "07.02.2026 14:17"],
[0, "08.02.2026 10:00"]
],
"sources": {
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["Поисковая фраза"],
"search_engines": {"1": 1}
}
},
"adsystems": {
"value": 20,
"enabled": true,
"settings": ["B2BContext"]
},
"backlinks": {
"value": 10,
"enabled": true,
"settings": {"list": ["https://example.com"]}
},
"messengers": {
"value": 5,
"enabled": true,
"settings": ["telegram"]
},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {
"value": 5,
"enabled": true,
"settings": ["pinterest"]
},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
}
}
PUT /group/{group_id}/
Назначение: полное обновление группы. В отличие от PATCH, метод PUT заменяет все настройки группы. Поля, не указанные в теле запроса, будут сброшены в значения по умолчанию. Валидация применяется ко всем полям.
Параметры URL:
group_id— ID группы.
Тело запроса: те же поля, что и в PATCH /group/{group_id}/.
Пример запроса:
curl -sS -X PUT "https://api.livesurf.ru/group/123/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{
"name": "My group",
"hour_limit": 100,
"day_limit": 10000,
"interval": [60, 300],
"uniq_ip": 0,
"moby_ratio": 0,
"geo": [1],
"timezone": "Europe/Moscow",
"autocalc_visits": {"enabled": false, "lower_at_night": false, "lower_at_week": false},
"sources": {
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["Поисковая фраза"],
"search_engines": {"1": 1}
}
}
}
}'
Пример ответа: структура как у GET /group/{group_id}/ (все поля группы).
DELETE /group/{group_id}/
Назначение: удалить группу и все вложенные страницы.
Параметры URL:
group_id— ID группы.
Пример ответа:
{"status": 1}
POST /group/{group_id}/clone/
Назначение: клонировать группу вместе со всеми её страницами.
Параметры URL:
group_id— ID группы.
Тело запроса:
name(string, опционально) — имя новой группы.
Пример ответа: полная структура как у GET /group/{group_id}/. Пример:
{
"id": 456,
"name": "My group copy 2",
"hour_limit": 50,
"day_limit": 1000,
"interval": [30, 180],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"stopping_hours": [],
"autocalc_visits": {"enabled": false, "lower_at_night": false, "lower_at_week": false},
"use_profiles": true,
"retention": true,
"description": "",
"timezone": "Europe/Moscow",
"category": 1,
"language": 2,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"schedules": [],
"low_pf": {"enabled": false, "ratio": 30},
"sources": {
"keywords": {"value": 50, "enabled": true, "settings": {"list": ["пример фразы"], "search_engines": {"1": 1}}},
"adsystems": {"value": 20, "enabled": true, "settings": ["B2BContext"]},
"backlinks": {"value": 10, "enabled": true, "settings": {"list": ["https://example.com"]}},
"messengers": {"value": 5, "enabled": true, "settings": ["telegram"]},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {"value": 5, "enabled": true, "settings": ["pinterest"]},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
},
"pages": [
{"id": 1001, "state": 0, "position": 0, "url": ["https://example.com/"], "showtime": [15, 30], "break_chain": 0, "adult": false, "group_id": 456, "behavior": {"mode": "disabled", "settings": {"reading_up": false, "clicks": {"list": []}}}},
{"id": 1002, "state": 0, "position": 1, "url": ["https://example.com/page2"], "showtime": [15, 30], "break_chain": 0, "adult": false, "group_id": 456, "behavior": {"mode": "disabled", "settings": {"reading_up": false, "clicks": {"list": []}}}}
],
"credits": 0
}
POST /group/{group_id}/add_credits/
Назначение: зачислить кредиты на проект в ручном режиме.
Параметры URL:
group_id— ID группы.
Тело запроса:
credits(int) — количество зачисляемых кредитов. Допускаются только положительные значения (больше 0). Метод доступен только в ручном режиме работы.
Пример запроса:
curl -sS -X POST "https://api.livesurf.ru/group/123/add_credits/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"credits": 100}'
Пример ответа:
{"status": 1}
POST /group/{group_id}/refund_credits/
Назначение: вернуть все кредиты проекта на основной баланс аккаунта (ручной режим).
Параметры URL:
group_id— ID группы.
Параметры тела: нет.
Пример ответа:
{"status": 1}
POST /group/{group_id}/reorder/
Назначение: изменить порядок страниц в группе. Порядок задаётся списком page_ids (первый элемент — position 0, второй — 1 и т.д.). После успеха GET /group/{group_id}/ и GET /group/all/ возвращают страницы в новом порядке. При неверном списке (не массив, пустой, есть ID не из группы, неполный или с дублями) возвращается 400 с полем errors.page_ids.
Параметры URL:
group_id— ID группы.
Тело запроса:
page_ids(array of int) — полный список ID страниц группы без дублей, в нужном порядке. Должен содержать ровно все страницы группы.
Пример запроса:
curl -sS -X POST "https://api.livesurf.ru/group/12345/reorder/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"page_ids": [102, 101, 103]}'
Пример ответа:
{"id": 12345}
POST /group/create/
Назначение: создать группу с вложенными страницами.
Поля тела запроса:
- Поддерживаются те же поля конфигурации группы, что и в
PATCH /group/{group_id}/. - Дополнительно:
pages(array) — список создаваемых страниц.- Для каждого элемента
pagesиспользуются поля изPOST /page/create/.
Важные ограничения:
sources.keywords.settings.list<=max_keywords.sources.backlinks.settings.list<=max_backlinks.- Общее число страниц аккаунта <=
max_total_pages.
Пример запроса (полная конфигурация с несколькими страницами и всеми источниками):
{
"name": "Группа 27",
"hour_limit": 50,
"day_limit": 10000,
"interval": [60, 300],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"timezone": "Europe/Moscow",
"autocalc_visits": {
"enabled": false,
"lower_at_night": false,
"lower_at_week": false
},
"use_profiles": true,
"retention": true,
"category": 1,
"language": 1,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"schedules": [
[1, "07.02.2026 14:17"],
[0, "08.02.2026 10:00"]
],
"pages": [
{
"url": ["https://example.com/", "https://example.com/page2"],
"showtime": [15, 30],
"state": 0,
"break_chain": 10
},
{
"url": ["https://example.com/page3", "https://example.com/page4"],
"showtime": [15, 30],
"state": 0,
"break_chain": 0
}
],
"sources": {
"keywords": {
"value": 50,
"enabled": true,
"settings": {
"list": ["ключевая фраза 1", "ключевая фраза 2"],
"search_engines": {"1": 1, "2": 0.5}
}
},
"adsystems": {
"value": 20,
"enabled": true,
"settings": ["B2BContext"]
},
"backlinks": {
"value": 10,
"enabled": true,
"settings": {"list": ["https://example.com"]}
},
"messengers": {
"value": 5,
"enabled": true,
"settings": ["telegram"]
},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {
"value": 5,
"enabled": true,
"settings": ["pinterest"]
},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
}
}
Пример ответа: полная структура как у GET /group/{group_id}/. Пример:
{
"id": 789,
"name": "Группа 27",
"hour_limit": 50,
"day_limit": 10000,
"interval": [60, 300],
"uniq_ip": 0,
"moby_ratio": 50,
"geo": [1, 2],
"stopping_hours": [],
"autocalc_visits": {"enabled": false, "lower_at_night": false, "lower_at_week": false},
"use_profiles": true,
"retention": true,
"description": "",
"timezone": "Europe/Moscow",
"category": 1,
"language": 1,
"bookmarks": [10, 40],
"autolimit": [-10, 10],
"schedules": [],
"low_pf": {"enabled": false, "ratio": 30},
"sources": {
"keywords": {"value": 50, "enabled": true, "settings": {"list": ["ключевая фраза 1"], "search_engines": {"1": 1}}},
"adsystems": {"value": 20, "enabled": true, "settings": ["B2BContext"]},
"backlinks": {"value": 10, "enabled": true, "settings": {"list": ["https://example.com"]}},
"messengers": {"value": 5, "enabled": true, "settings": ["telegram"]},
"clickunders": {"value": 5, "enabled": true},
"emailanalytics": {"value": 5, "enabled": true},
"socialanalytics": {"value": 5, "enabled": true, "settings": ["pinterest"]},
"neurals": {"value": 0, "enabled": false, "settings": []},
"recommenders": {"value": 0, "enabled": false, "settings": []},
"qrcodes": {"value": 0, "enabled": false}
},
"pages": [
{"id": 1001, "state": 0, "position": 0, "url": ["https://example.com/", "https://example.com/page2"], "showtime": [15, 30], "break_chain": 10, "adult": false, "group_id": 789, "behavior": {"mode": "disabled", "settings": {"reading_up": false, "clicks": {"list": []}}}}
],
"credits": 0
}
Пример ошибки валидации (400):
{
"errors": {
"pages": ["Ensure this field has at least 1 elements."]
}
}
Страницы
GET /page/{page_id}/
Назначение: получить конфигурацию страницы.
Параметры URL:
page_id— ID страницы.
Примечание: ID страниц можно получить через GET /group/{group_id}/.
Пример ответа:
{
"id": 1086337,
"state": 1,
"position": 3,
"url": ["https://example.com/"],
"showtime": [15, 45],
"break_chain": 10,
"adult": false,
"group_id": 123,
"behavior": {
"mode": "neural",
"settings": {
"reading_up": true,
"clicks": {
"list": ["a", ".css-class", "#css-id"]
}
}
}
}
PATCH /page/{page_id}/
Назначение: частично обновить страницу. Обновляются только переданные поля.
Параметры URL:
page_id— ID страницы.
Основные поля тела:
state(int):0пауза,1работа.break_chain(int): вероятность прерывания цепочки (0–100).url(array[string]): список URL на одном домене, максимум1 + max_alternate_urls.showtime(array[int,int]):[from, to], каждое значение отдельно ограниченоmin_showtime..max_showtime.behavior(object): настройки поведения.
behavior.mode:
disabled— поведение отключено.clicks— клик по заданным селекторам.fixation— фиксация посетителя кликом в конце.neural— поведение генерируется нейросетью.manual— ручная настройка поведения через JSON-сценарий действий.
behavior.settings:
reading_up(bool) — дочитывание: добавляет поведение доскролла до нижней части страницы в любом режиме, кроме режима ручной настройки поведения.clicks.list(array[string]) — CSS селекторы для режимаclicks, максимумmax_selectors. Клик выполняется по одному из селекторов списка, выбранному случайным образом в начале посещения.
behavior.manual (только для mode = "manual"):
actions(object) — JSON-сценарий действий на странице. Структуру и справочник всех действий см. в разделе Поведение в режимеmanualниже.
Пример запроса:
curl -sS -X PATCH "https://api.livesurf.ru/page/1086337/" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{
"url": ["https://example.com/page_1.html", "https://example.com/page_2.html"],
"break_chain": 10,
"showtime": [30, 45],
"behavior": {
"mode": "neural",
"settings": {
"reading_up": true,
"clicks": {"list": ["a", "span", "#awesome_button"]}
}
},
"state": 1
}'
Пример ответа:
{"id": 1086337}
PUT /page/{page_id}/
Назначение: полное обновление страницы. В отличие от PATCH, метод PUT заменяет все настройки страницы. Поля, не указанные в теле запроса, будут сброшены в значения по умолчанию. Валидация применяется ко всем полям.
Параметры URL:
page_id— ID страницы.
Тело запроса: те же поля, что и в PATCH /page/{page_id}/.
Пример ответа:
{"id": 1086337}
DELETE /page/{page_id}/
Назначение: удалить страницу. Если в группе остаётся 0 страниц, группа тоже удаляется.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"status": 1}
POST /page/create/
Назначение: создать новую страницу.
Поля тела:
group_id(int) — ID группы.state(int) —0/1.break_chain(int) — вероятность прерывания (0–100).url(array[string]) — до1 + max_alternate_urls.showtime(array[int,int]) — каждое значение вmin_showtime..max_showtime.behavior(object) — настройки поведения.
Пример запроса:
{
"group_id": 123,
"state": 0,
"break_chain": 10,
"url": ["https://example.com/", "https://example.com/page2"],
"showtime": [15, 30],
"behavior": {
"mode": "disabled",
"settings": {
"reading_up": true,
"clicks": {
"list": ["a"]
}
}
}
}
Пример ответа:
{"id": 1}
Пример ошибки валидации (400):
{
"errors": {
"group_id": "Group with group_id=0 does not exist"
}
}
POST /page/{page_id}/clone/
Назначение: клонировать страницу в рамках группы и поместить новую страницу в конец списка страниц.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"id": 1087000}
POST /page/{page_id}/up/
Назначение: поднять страницу на 1 позицию вверх в списке.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"status": 1}
POST /page/{page_id}/down/
Назначение: опустить страницу на 1 позицию вниз в списке.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"status": 1}
POST /page/{page_id}/start/
Назначение: запустить страницу.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"status": 1}
POST /page/{page_id}/stop/
Назначение: остановить страницу.
Параметры URL:
page_id— ID страницы.
Пример ответа:
{"status": 1}
Поведение в режиме manual
Режим manual (behavior.mode = "manual") — это сценарий поведения, который браузер пошагово выполняет на странице. Сценарий описывается как граф из блоков: один блок — одно действие (подождать, кликнуть, прочитать текст, проверить условие). Блоки связаны переходами и запускаются триггерами.
Раздел длинный. Чтобы быстрее начать — см. Минимальный пример и затем Готовые рецепты.
Как это работает
Пример сценария «дождаться кнопку .cta и кликнуть» в виде блок-схемы:
flowchart TD
A([Триггер afterload]) --> B["wait — пауза 1–2 сек"]
B -->|next| C{"Кнопка .cta видна?"}
C -->|success| D["clickTo — клик по .cta"]
C -->|failure| E["moveToDown — проскроллить вниз"]
E -->|next| C
D --> F([Конец цепочки])
Сценарий запускается триггером (afterload — после загрузки страницы, beforeendtask — перед завершением задания) и идёт от блока к блоку по полю next. У condition вместо next — два именованных выхода success и failure.
Минимальный пример
Подождать пару секунд после загрузки и кликнуть по баннеру cookies:
{
"behavior": {
"mode": "manual",
"manual": {
"actions": {
"triggers": {
"afterload": [{"enter": ["*"], "action": "wait"}]
},
"blocks": [
{"id": "wait", "action": "wait", "value": [1500, 3000], "next": ["click"]},
{"id": "click", "action": "clickTo",
"value": {"selector": [".cookies-accept"],
"modifiers": {"button": "left", "count": 1, "keys": [], "hold": false}}}
]
}
}
}
}
Здесь видно всё ключевое: триггер afterload запускает блок wait, тот передаёт управление по next в clickTo, который кликает по селектору. Дальше — добавляем блоки и переходы под нужный сценарий.
Структура actions
behavior.manual.actions — объект с тремя секциями:
{
"variables": { /* переменные сценария */ },
"triggers": { /* точки входа: afterload, beforeendtask */ },
"blocks": [ /* массив блоков-действий */ ]
}
| Поле | Обязательное | Что это |
|---|---|---|
variables |
нет | Именованные хранилища значений сценария. |
triggers |
нет | Точки входа: какое событие запускает какой блок. |
blocks |
да | Сами действия. Должен быть хотя бы один блок. |
Глоссарий
| Термин | Что это |
|---|---|
| Блок | Один шаг сценария: wait, clickTo, condition и т.п. У каждого свой id. |
Действие (action) |
Тип блока. Строка из справочника ниже. |
| Триггер | Точка входа в сценарий: какое событие запускает какой блок. |
next |
Куда идти после блока (массив id блоков-получателей, обычно один). |
success / failure |
Именованные выходы у condition вместо next. |
| Переменная | Именованное хранилище значений, доступное через подстановки. |
variables — переменные
Объект { "<имя>": <начальное_значение> }. До 20 переменных.
- Имя —
[a-zA-Z0-9]{0,15}. - Значение —
intили строка[a-zA-Z0-9]{0,15}. - Зарезервированы:
time,lsc_timer(используются исполнителем).
"variables": {"counter": 0, "phrase": "hello"}
triggers — точки входа
Триггер — это вход в граф. Он отвечает на вопросы «когда» (afterload / beforeendtask) и «куда» (с какого id стартовать).
"triggers": {
"afterload": [{"enter": ["*"], "action": "start"}],
"beforeendtask": [{"enter": ["*"], "action": "wrapup"}]
}
| Триггер | Когда срабатывает |
|---|---|
afterload |
После полной загрузки URL страницы. |
beforeendtask |
Перед завершением задания посещения. |
Поля точки входа:
enter(array[string]) — для каких URL применяется триггер.["*"]— любой URL текущей страницы; либо массив конкретных URL — триггер сработает только на них (страница может содержать несколько URL: основной + альтернативные).action(string) —idблока, с которого стартует цепочка.
blocks — блоки действий
{
"id": "<уникальный_id>",
"action": "<имя_действия>",
"value": <данные_действия>,
"next": ["<id_следующего>"]
}
id— уникальный в рамках сценария,[a-zA-Z0-9]{1,15}.action— название действия из справочника ниже.value— параметры. ДляmoveToDown,moveToUp,random,endотсутствует (или{}). Для остальных — обязательно.next—id-получатели по обычному выходу. 0..10 элементов (пустой массив = конец цепочки). Уconditionполяnextнет — естьsuccess/failureвнутриvalue.
Подстановки и :last-element
В строках CSS-селекторов и текстовых значениях ряда действий доступны подстановки:
livesurf.ru— текущий домен страницы.{<имя_переменной>}— значение переменной сценария.
Пример: «положить значение переменной baz в input, чей id определяется значением переменной bar»:
{"id": "step", "action": "setAttribute",
"value": {"selector": ["#{bar}"], "attr": "value", "variable": "baz"}}
Псевдо-селектор :last-element — последний элемент, найденный действием getElement. Удобно когда селектор сложный или одноразовый: нашли один раз, потом ссылаемся как на :last-element.
Лимиты (сводно)
| Где | Лимит |
|---|---|
Размер всего actions (UTF-8) |
25 KiB |
Идентификаторы (id блоков, имена переменных) |
[a-zA-Z0-9], до 15 символов |
| Количество переменных | до 20 |
next.length |
0..10 |
Количество селекторов в selector |
до 100 |
| Длина одного CSS-селектора | 1..500 символов |
Длина имени атрибута (attr) |
до 25 символов |
Справочник действий
Действия сгруппированы по назначению. По умолчанию массив selector принимает от 1 до 100 элементов; конкретные нюансы (мин-количество, опциональность) отмечены в каждом действии.
Поток управления
wait — пауза
value(array[int, int]) —[min_ms, max_ms], миллисекунды. Каждое значение0..180000,min ≤ max. Фактическая пауза выбирается случайно из диапазона.
{"id": "p", "action": "wait", "value": [1000, 3000], "next": ["nxt"]}
condition — ветвление
Имеет два именованных выхода success / failure внутри value. Поле next у блока не задаётся.
value.success(array[string], 1..10) —idблоков по ветви «истина».value.failure(array[string], 1..10) —idблоков по ветви «ложь».
Плюс один из трёх режимов проверки:
По наличию элемента — есть ключ selector:
"value": {"selector": [".cta"], "success": ["click"], "failure": ["fallback"]}
Истина, если найден хотя бы один из селекторов.
По переменной — есть ключи variable, sign, value:
"value": {"variable": "tries", "sign": "<", "value": 5,
"success": ["retry"], "failure": ["giveUp"]}
sign:<,>,=. Для строк допустим только=.value:intили строка (до 100 символов).
По состоянию курсора — есть ключ selected:
"value": {"selected": ["#btn"], "success": ["ok"], "failure": ["bad"]}
Истина, если курсор сейчас наведён на один из элементов (использовать после moveTo).
shuffle — случайные движения
value.duration(array[int, int]) —[min_sec, max_sec], секунды. Каждое1..30,min ≤ max.value.modifiers(array[string], optional) —["click"]чтобы разрешить случайные клики во время shuffle; пустой массив / отсутствие поля — только движения курсора.
{"id": "shuf", "action": "shuffle",
"value": {"duration": [3, 5], "modifiers": ["click"]}}
random — случайное ветвление
Без value. Передаёт управление случайному блоку из next.
{"id": "branch", "action": "random", "next": ["a", "b", "c"]}
end — конец цепочки
value:{}.nextне задаётся.
Завершает поток выполнения.
Курсор и клики
moveTo — навестись на элемент
value.selector(array[string], до 10) — CSS-селекторы. Выбирается случайный из найденных.value.drag(bool, optional) —trueимитирует драг (drag-and-drop междуclickTo(hold:true)иclickRelease; актуально и для тач-устройств).
clickTo — клик по элементу
value.selector(array[string], 1..10) — CSS-селекторы.value.modifiers(object, required):button:"left"|"middle"|"right".count(int, 1..10) — количество кликов.keys(array of"shift"|"ctrl"|"alt") — клавиши-модификаторы во время клика.hold(bool) — удерживать кнопку до парногоclickRelease.
{"id": "c", "action": "clickTo",
"value": {"selector": [".cta"],
"modifiers": {"button": "left", "count": 1, "keys": [], "hold": false}}}
click — клик в текущей позиции курсора
Как clickTo, но без selector — кликает там, где сейчас курсор. modifiers те же.
clickRelease — отпустить удерживаемую кнопку
value.button:"left"|"middle"|"right". Парный кclickToсhold: true.
Прокрутка и фокус
scrollTo — проскроллить к элементу
value.selector(array[string], до 10) — CSS-селекторы.
moveToDown — проскроллить страницу вниз
Без value.
moveToUp — проскроллить страницу вверх
Без value.
focus — установить фокус
value.selector(array[string], до 10) — CSS-селекторы.
Поиск и работа с DOM
findText — поиск текста / элемента / атрибута
Дискриминатор value.type определяет режим.
type: "text" — поиск подстроки на странице:
value.pattern(string, 1..100) — что искать.value.mode:"Text"(видимый текст) или"HTML"(HTML-разметка).value.variable(string) — куда положить результат.
{"action": "findText",
"value": {"type": "text", "pattern": "Test Passed",
"mode": "Text", "variable": "found"}}
type: "element" — поиск элемента, результат в переменную. Поле attr опционально.
type: "attribute" — поиск элемента и чтение его атрибута в переменную (attr обязателен):
{"action": "findText",
"value": {"type": "attribute", "selector": ["#uniqText"],
"attr": "value", "variable": "saved"}}
getElement — найти и закешировать элемент
value.selector(array[string], до 10) — CSS-селекторы.
После выполнения найденный элемент доступен в последующих действиях через псевдо-селектор :last-element (см. Рецепт 10).
removeElement — удалить элемент из DOM
value.selector(array[string], min 1) — удаляются все найденные.
setAttribute — установить атрибут на элементе
value.selector(array[string], min 1) — CSS-селекторы.value.attr(string, до 25 символов) — имя атрибута.- Источник значения — одно из (взаимно исключающие):
value.value(string, до 100 символов) — литерал;value.variable(string) — значение из переменной.
setAttrToVar — сохранить значение атрибута в переменную
value.selector(array[string], min 1) — если найдено несколько элементов, значения склеиваются через запятую.value.attr(string, до 25 символов).value.variable(string) — куда сохранить.
removeAttribute — удалить атрибут с элемента
value.selector(array[string], min 1) — CSS-селекторы.value.attr(string, до 25 символов) — имя атрибута.
Ввод текста
type — печать текста в активном элементе
-
value.strings(array[string], 1..100) — список вариантов, выбирается случайный. Каждая строка — до 255 символов. Допускаются спец-токены:Токен Клавиша k-enterEnter k-tabTab k-spaceSpace k-backspaceBackspace k-deleteDelete k-upk-downk-leftk-rightстрелки -
value.modifiers.count(int, 1..100, optional) — повторить ввод выбранной строки N раз.
{"action": "type", "value": {"strings": ["k-enter"]}}
Переменные
setVar — изменить значение переменной
-
value.variable(string) — имя цели. -
value.set.mode— режим:Режим set.valueСмысл "val"intили строка до 100 символовПрисвоить литерал. "var"имя другой переменной (string) Присвоить значение этой переменной. "incr"int1..1000Увеличить целевую переменную на N. "decr"int1..1000Уменьшить целевую переменную на N.
{"action": "setVar",
"value": {"variable": "counter", "set": {"mode": "incr", "value": 1}}}
Готовые рецепты
Самодостаточные фрагменты actions, скопировать → положить в behavior.manual.actions. Все примеры — варианты реальных сценариев из тестового набора редактора.
Рецепт 1: подождать 5 секунд
{
"triggers": {"afterload": [{"enter": ["*"], "action": "wait1"}]},
"blocks": [
{"id": "wait1", "action": "wait", "value": [5000, 5000]}
]
}
Рецепт 2: найти текст и вставить в input
{
"triggers": {"afterload": [{"enter": ["*"], "action": "find"}]},
"blocks": [
{"id": "find", "action": "findText",
"value": {"type": "text", "pattern": "Test Passed",
"mode": "Text", "variable": "found"},
"next": ["paste"]},
{"id": "paste", "action": "setAttribute",
"value": {"selector": ["#textarea", "#textInput"],
"attr": "value", "variable": "found"}}
]
}
Рецепт 3: прочитать атрибут одного элемента и вставить в другой
{
"triggers": {"afterload": [{"enter": ["*"], "action": "read"}]},
"blocks": [
{"id": "read", "action": "findText",
"value": {"type": "attribute", "selector": ["#uniqText"],
"attr": "value", "variable": "found"},
"next": ["paste"]},
{"id": "paste", "action": "setAttribute",
"value": {"selector": ["#textarea"], "attr": "value", "variable": "found"}}
]
}
Рецепт 4: ввод текста и спец-клавиш по цепочке
{
"triggers": {"afterload": [{"enter": ["*"], "action": "t1"}]},
"blocks": [
{"id": "t1", "action": "type", "value": {"strings": ["HelloWorld"]}, "next": ["t2"]},
{"id": "t2", "action": "type", "value": {"strings": ["k-enter"]}, "next": ["t3"]},
{"id": "t3", "action": "type", "value": {"strings": ["k-tab"]}}
]
}
Рецепт 5: серия кликов по разным элементам
{
"triggers": {"afterload": [{"enter": ["*"], "action": "c1"}]},
"blocks": [
{"id": "c1", "action": "clickTo",
"value": {"selector": ["#uid1"], "modifiers": {"count": 1, "button": "left"}},
"next": ["c2"]},
{"id": "c2", "action": "clickTo",
"value": {"selector": ["#uid2"], "modifiers": {"count": 1, "button": "left"}}}
]
}
Рецепт 6: drag-and-drop
{
"triggers": {"afterload": [{"enter": ["*"], "action": "grab"}]},
"blocks": [
{"id": "grab", "action": "clickTo",
"value": {"selector": ["#topLeftSquare"],
"modifiers": {"count": 1, "button": "left", "hold": true}},
"next": ["drag"]},
{"id": "drag", "action": "moveTo",
"value": {"drag": true, "selector": ["#bottomRightSquare"]},
"next": ["drop"]},
{"id": "drop", "action": "clickRelease", "value": {"button": "left"}}
]
}
Рецепт 7: проскроллить вниз и обратно вверх
{
"triggers": {"afterload": [{"enter": ["*"], "action": "s1"}]},
"blocks": [
{"id": "s1", "action": "moveToDown", "next": ["s2"]},
{"id": "s2", "action": "moveToUp"}
]
}
Рецепт 8: проскроллить точно к кнопке и кликнуть
{
"triggers": {"afterload": [{"enter": ["*"], "action": "scroll"}]},
"blocks": [
{"id": "scroll", "action": "scrollTo",
"value": {"selector": ["#finishBtn"]}, "next": ["click"]},
{"id": "click", "action": "clickTo",
"value": {"selector": ["#finishBtn"],
"modifiers": {"count": 1, "button": "left"}}}
]
}
Рецепт 9: фокус по нескольким полям подряд
{
"triggers": {"afterload": [{"enter": ["*"], "action": "f1"}]},
"blocks": [
{"id": "f1", "action": "focus", "value": {"selector": ["#inputText"]}, "next": ["f2"]},
{"id": "f2", "action": "focus", "value": {"selector": ["#aLink"]}, "next": ["f3"]},
{"id": "f3", "action": "focus", "value": {"selector": ["#buttOn"]}}
]
}
Рецепт 10: getElement + :last-element
Когда селектор страшный или одноразовый — нашли один раз через getElement, дальше ссылаемся как :last-element:
{
"triggers": {"afterload": [{"enter": ["*"], "action": "find"}]},
"blocks": [
{"id": "find", "action": "getElement",
"value": {"selector": ["#page1Btn"]}, "next": ["clk"]},
{"id": "clk", "action": "clickTo",
"value": {"selector": [":last-element"],
"modifiers": {"count": 1, "button": "left"}}}
]
}
Рецепт 11: переменные и подстановка {name} в селекторе
{
"variables": {"foo": 3, "bar": "baz"},
"triggers": {"afterload": [{"enter": ["*"], "action": "step1"}]},
"blocks": [
{"id": "step1", "action": "setVar",
"value": {"variable": "baz", "set": {"mode": "var", "value": "foo"}},
"next": ["step2"]},
{"id": "step2", "action": "setAttribute",
"value": {"selector": ["#{bar}"], "attr": "value", "variable": "baz"}}
]
}
Сначала кладём в baz значение foo (= 3). Затем подставляем в селектор #{bar} значение переменной bar (= "baz") — получаем #baz — и пишем туда значение переменной baz (= 3).
Рецепт 12: цикл со счётчиком и числовое сравнение
«Повторять 5 раз с паузой по 500 мс, потом завершиться»:
{
"variables": {"tries": 0},
"triggers": {"afterload": [{"enter": ["*"], "action": "inc"}]},
"blocks": [
{"id": "inc", "action": "setVar",
"value": {"variable": "tries", "set": {"mode": "incr", "value": 1}},
"next": ["chk"]},
{"id": "chk", "action": "condition",
"value": {"variable": "tries", "sign": "<", "value": 5,
"success": ["pause"], "failure": ["stop"]}},
{"id": "pause", "action": "wait", "value": [500, 500], "next": ["inc"]},
{"id": "stop", "action": "end", "value": {}}
]
}
Рецепт 13: «дождаться кнопку и кликнуть» (poll-pattern)
«Скроллить вниз с паузами, пока на странице не появится кнопка .cta-button, потом кликнуть»:
{
"triggers": {"afterload": [{"enter": ["*"], "action": "check"}]},
"blocks": [
{"id": "check", "action": "condition",
"value": {"selector": [".cta-button"],
"success": ["click"], "failure": ["scroll"]}},
{"id": "scroll", "action": "moveToDown", "next": ["pause"]},
{"id": "pause", "action": "wait", "value": [300, 700], "next": ["check"]},
{"id": "click", "action": "clickTo",
"value": {"selector": [".cta-button"],
"modifiers": {"count": 1, "button": "left"}}}
]
}
Рецепт 14: обмен значений между двумя input через переменную
{
"triggers": {"afterload": [{"enter": ["*"], "action": "read"}]},
"blocks": [
{"id": "read", "action": "setAttrToVar",
"value": {"selector": ["#inputText1"], "attr": "value", "variable": "temp"},
"next": ["clear"]},
{"id": "clear", "action": "setAttribute",
"value": {"selector": ["#inputText1"], "attr": "value", "value": ""},
"next": ["paste"]},
{"id": "paste", "action": "setAttribute",
"value": {"selector": ["#inputText2"], "attr": "value", "variable": "temp"}}
]
}
Статистика
GET /pages-compiled-stats/
Назначение: статистика показов по странице или группе за дату/период. Максимальный диапазон дат — 7 дней.
Параметры query:
page_id(int) илиgroup_id(int)- и один из вариантов периода:
date(YYYY-MM-DD)date_from+date_to(YYYY-MM-DD)
Пример запроса:
curl -sS "https://api.livesurf.ru/pages-compiled-stats/?group_id=123&date=2026-02-19" \
-H "Authorization: <API_KEY>" \
-H "Accept: application/json"
Пример ответа:
[
{
"group_id": 123,
"page_id": 1086337,
"visits": 42,
"credits": 98,
"date": "19.02.2026",
"date_update": "19.02.2026 15:57:24"
}
]
Пример ошибки (400):
{
"errors": {
"non_field_errors": [
"required parameter \"date\" or parameters \"date_from\" and \"date_to\""
]
}
}
Практика использования
- Прежде чем строить UI и валидировать формы — запросите
GET /limits/.
Оттуда придёт: тариф текущего юзера (user.limits) с порогамиmax_*для
self-валидации, таблицаpricing.showtime_price({secs: base_price}),
и список активныхpricing.modifiers(надбавки/скидки в процентах от базы;
применяются мультипликативно:final = base × Π(1 + modifier.value)по всем
enabled=true). - Авторизация — заголовок
Authorization: <token>.401/403=
«нет токена» / «токен валиден, но операция не разрешена для тарифа». - Рейт-лимит клиентского API — 10 rps на токен. При превышении вернётся
429; на массовых операциях разбивайте поток во времени. - Ошибки валидации возвращаются как
400с полемerrors. Конкретные
сообщения лежат вerrors.<field_name>илиerrors.non_field_errors—
на них и завязывайте показ ошибок пользователю.
LIVEsurf
RU
IT