Документация 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_keywords
    • settings.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 отсутствует (или {}). Для остальных — обязательно.
  • nextid-получатели по обычному выходу. 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-enter Enter
    k-tab Tab
    k-space Space
    k-backspace Backspace
    k-delete Delete
    k-up k-down k-left k-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" int 1..1000 Увеличить целевую переменную на N.
    "decr" int 1..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
    на них и завязывайте показ ошибок пользователю.