WebScript (уведомления прямо со страницы)
WebScript — это лёгкий способ получать уведомления прямо с чужой/своей
веб-страницы, ничего не трогая в бекенде. Вы создаёте «скрипт» в Notifly,
указываете тип события (открытие страницы / отправка формы / клик по кнопке /
ошибки консоли) — и получаете готовый HTML-сниппет с публичным URL вида
/script/T<token>.
Вставляете его в шаблон сайта, в виджет, в письмо, в README — каждый раз, когда событие срабатывает, в выбранный канал прилетает уведомление.
Удобно для:
- сайтов на «коробочной» CMS, где сложно дотянуться до бекенда;
- лендингов и форм на статике (Tilda, GitHub Pages, Netlify);
- быстрых экспериментов («хочу пинг каждый раз, когда кто-то жмёт Купить»);
- виджетов в админках сторонних SaaS, куда можно вставить только
<script>; - замены Sentry/Bugsnag для pet-проектов и небольших команд.
Типы скриптов
Заголовок раздела «Типы скриптов»Поддерживается четыре предустановленных шаблона. Сниппет с готовым HTML/JS вы скопируете прямо из админки — здесь только описание поведения.
scriptType | Когда срабатывает | Что попадает в message |
|---|---|---|
page_open | При загрузке страницы (<script> исполняется) | Страница: <title> + URL: <location> |
form_submit | При сабмите любой <form> на странице | Все непустые поля формы (name: value) |
button_click | При клике на элемент с атрибутом data-notifly | Текст атрибута data-notifly или текстовое содержимое + URL |
console_errors | При возникновении JS-ошибки в браузере | Карточка ошибки: стектрейс, URL, браузер, breadcrumbs |
Триггерные сниппеты (page_open, form_submit, button_click) отправляют
POST на /script/T<token> с application/json-телом {title, message},
console_errors — батч ошибок (формат ниже). Это публичный эндпоинт, не
требующий авторизации (аутентификацией служит сам T<token> в URL).
Каждое созданное уведомление — одно событие дневной квоты. Это обычное сообщение канала: на него действуют эскалация, тихие часы и окна обслуживания канала.
Создание скрипта
Заголовок раздела «Создание скрипта»Через админку
Заголовок раздела «Через админку»- Откройте app.notifly.ru → Интеграции → Скрипты для сайта.
- Нажмите «Создать скрипт», заполните:
- Название — для отображения, например «Лендинг — клик “Купить”».
- Канал — куда слать уведомления (только ваш собственный канал).
- Тип скрипта — «Открытие страницы», «Отправка формы», «Клик на кнопку» или «Ошибки консоли». Тип нельзя изменить после создания.
- Заголовок уведомления —
titleсообщения по умолчанию. - Приоритет (0-10) — 0 = взять
defaultPriorityканала. - Для «Ошибок консоли» — ещё Порог уведомления и Окружения (см. ниже).
- На карточке скрипта — готовый код во вкладках: HTML вставка, SDK в
коде (только для ошибок консоли), Google Tag Manager и Для LLM.
HTML-вставку можно скопировать в
<head>сайта или в любое место<body>.
Через REST API
Заголовок раздела «Через REST API»curl -X POST "$NOTIFLY_URL/web-script" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{ "name": "Лендинг — клик «Купить»", "appId": 12345, "scriptType": "button_click", "title": "Клик «Купить» на лендинге", "priority": 3 }'Для console_errors:
curl -X POST "$NOTIFLY_URL/web-script" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{ "name": "Production — ошибки фронтенда", "appId": 12345, "scriptType": "console_errors", "title": "JS Error", "priority": 8, "notifyThreshold": "error", "environments": "production" }'В ответе придёт объект скрипта с публичным token (префикс T):
{ "id": 8, "token": "T7c2a8f3b1e0d4a6c8e9f", "appId": 12345, "appName": "Marketing", "name": "Лендинг — клик «Купить»", "scriptType": "button_click", "title": "Клик «Купить» на лендинге", "priority": 3, "notifyThreshold": "", "environments": "", "created": "2026-04-30T10:11:12Z", "lastUsed": null}Полный URL для триггера — ${NOTIFLY_URL}/script/T7c2a8f3b1e0d4a6c8e9f (в
примерах токен укорочен; настоящий — T и 40 hex-символов).
Обязательные поля — name (до 200 символов), appId и scriptType;
priority — 0–10. PUT /web-script/:id принимает то же тело, scriptType в нём
должен совпадать с текущим. На аккаунт — до 500 скриптов.
Готовые сниппеты
Заголовок раздела «Готовые сниппеты»Все три триггерных сниппета — вариации одного и того же
fetch(url, {method: "POST", ...}). Они никогда не ломают страницу
(.catch(function(){})) и не требуют CORS-настроек: /script/:token отвечает
с разрешающими CORS-заголовками для любого домена.
page_open — пинг при открытии страницы
Заголовок раздела «page_open — пинг при открытии страницы»<!-- Notifly — уведомление при открытии страницы --><script> (function () { fetch('https://api.notifly.ru/script/T7c2a8f3b1e0d4a6c8e9f', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ title: 'Лендинг — клик «Купить»', message: 'Страница: ' + document.title + '\n\nURL: ' + location.href, }), }).catch(function () {}); })();</script>form_submit — пинг при отправке формы
Заголовок раздела «form_submit — пинг при отправке формы»Скрипт навешивается на все <form> на странице, собирает все непустые
поля и отправляет их в теле уведомления:
<script> document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('form').forEach(function (form) { form.addEventListener('submit', function () { var fd = new FormData(form); var lines = []; fd.forEach(function (v, k) { if (v) lines.push(k + ': ' + v); }); fetch('https://api.notifly.ru/script/T...', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ title: 'Заявка с сайта', message: lines.join('\n\n') || '(пустая форма)', }), }).catch(function () {}); }); }); });</script>button_click — пинг при клике на элемент
Заголовок раздела «button_click — пинг при клике на элемент»Срабатывает только для элементов, у которых есть атрибут data-notifly:
<script> document.addEventListener('click', function (e) { var el = e.target.closest('[data-notifly]'); if (!el) return; var label = el.getAttribute('data-notifly') || el.textContent.trim() || 'кнопка'; fetch('https://api.notifly.ru/script/T...', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ title: 'Клик «Купить»', message: 'Клик: ' + label + '\n\nСтраница: ' + location.href, }), }).catch(function () {}); });</script><!-- Пример использования: --><button data-notifly="Заказать">Заказать</button>console_errors — перехват ошибок консоли (Sentry-lite)
Заголовок раздела «console_errors — перехват ошибок консоли (Sentry-lite)»Самый мощный тип скрипта — полноценный перехватчик JS-ошибок, работающий как
облегчённый аналог Sentry / Bugsnag / TrackJS. Для него используется hosted SDK
(error-sdk.js), который Notifly раздаёт со своего CDN — готовый сниппет с вашим
токеном генерируется в админке на карточке скрипта. SDK ловит:
window.onerror— все необработанные исключения (включая ошибки загрузки ресурсов);unhandledrejection— отклонённые промисы без.catch();console.error(...)— превращается в полноценное событие, даже безthrow;- CSP-нарушения (
securitypolicyviolation) — событием уровняwarning; - ручные вызовы —
ErrorSDK.captureException(err, ctx)иErrorSDK.captureMessage(msg, level, ctx).
Особенности:
- Breadcrumbs — SDK буферизует вызовы
console.error/warn/log/info,fetch/XHR, клики и SPA-навигацию; последние крошки прикладываются к ошибке («что было перед ней»). - Батчинг — ошибки копятся в очередь и отправляются пачкой (до 10 шт или каждые 3 сек).
- Дедупликация на клиенте — одна и та же ошибка не отправляется повторно в окне ~10 сек.
- Дедупликация на сервере — по одной проблеме уведомление приходит не чаще раза в 2 минуты; повторы в этом окне только увеличивают счётчик.
- Sampling —
sampleRate(1 = всё) прореживает отправку на клиенте; сервер экстраполирует счётчики. - Лимит запросов — максимум 100 POST-ов за загрузку страницы, чтобы не попасть в бесконечный цикл.
- sendBeacon — используется
navigator.sendBeaconпри уходе со страницы (не блокирует навигацию). - Финальный flush — при
pagehide/ скрытии вкладки скрипт отправляет оставшуюся очередь. - Санитизация — секреты (password/token/cookie/…) и чувствительные query-параметры вырезаются и на клиенте, и повторно на сервере.
- 1 батч = не больше одного уведомления и одного события квоты. Если уведомлять
не о чем (всё — повторы в окне дедупликации, ниже порога или из чужого окружения),
сервер отвечает
{"ok": true, "deduped": true}и квоту не тратит.
<!-- Notifly — перехват ошибок браузера (hosted SDK) --><script src="https://app.notifly.ru/static/error-sdk.js" crossorigin="anonymous"></script><script> // window.NOTIFLY_RELEASE можно задать ДО этого скрипта, чтобы помечать события релизом. window.ErrorSDK && window.ErrorSDK.init({ endpoint: 'https://api.notifly.ru/script/T...', app: 'My App', release: window.NOTIFLY_RELEASE || '', environment: 'production', sampleRate: 1, maxBreadcrumbs: 20, });</script>Параметры init():
| Параметр | Описание |
|---|---|
endpoint | Публичный URL скрипта POST /script/T<token> (обязателен) |
app | Название приложения — уходит в поле title батча (заголовок уведомления строится из первой ошибки) |
release | Метка релиза (git-sha / версия) — нужна для source maps |
environment | Окружение (production / staging / …, по умолчанию production) — сверяется с allowlist скрипта |
sampleRate | Доля отправляемых ошибок, 1 = все |
notifyThreshold | Клиентская подсказка порога уведомлений (сервер решает по настройке скрипта) |
maxBreadcrumbs | Сколько «крошек» прикладывать к ошибке (по умолчанию 20; больше 30 сервер отклонит) |
ignoreErrors | Не отправлять ошибки, чьё сообщение совпало (строка — вхождение, RegExp — проверка) |
denyUrls / allowUrls | Фильтр по URL источника ошибки (верхний кадр стека) |
beforeSend | function (event) { … } — последний хук перед отправкой; null = не отправлять |
Отфильтрованные на клиенте события не уходят на сервер вовсе — не тратят квоту и не попадают в проблемы и графики.
Формат данных
Заголовок раздела «Формат данных»SDK формирует батч сам; ниже — схема для кастомных интеграций. Тело запроса
POST /script/T<token> (макс. 64 KiB, до 50 ошибок в батче):
{ "title": "My App", "release": "v1.2.3", "environment": "production", "sampleRate": 1, "flushReason": "batch", "errors": [ { "eventId": "3f2a…", "type": "error", "level": "error", "message": "Cannot read properties of undefined (reading 'map')", "stack": "TypeError: Cannot read properties...\n at App.tsx:42:12\n at ...", "url": "https://example.com/dashboard", "lineno": 42, "colno": 12, "userAgent": "Mozilla/5.0 ...", "ts": 1716556800000, "sentAt": "2026-07-14T12:00:00.000Z", "exception": {"name": "TypeError", "message": "...", "stack": "..."}, "runtime": { "url": "https://example.com/dashboard", "path": "/dashboard", "referrer": "https://example.com/", "userAgent": "Mozilla/5.0 ...", "language": "ru-RU", "viewport": "1920x1080" }, "context": {"feature": "checkout"}, "breadcrumbs": [ { "category": "ui.click", "level": "info", "message": "", "data": {"target": "button#pay"}, "timestamp": "2026-07-14T11:59:58.000Z" } ] } ]}Обязательные поля каждой ошибки: message, type (error | unhandledrejection |
console.error | exception | message), level (info | warning | error |
fatal), runtime.url и sentAt (RFC3339). Батч без environment, с неизвестным
type/level, с более чем 50 ошибками или 30 breadcrumbs на ошибку отклоняется с
кодом 400; тело больше 64 KiB — 413. Сервер повторно санитизирует всё
присланное: чувствительные ключи и query-параметры, JWT/Bearer-токены, email,
телефоны, номера карт и публичные IP заменяются на [Filtered].
Сервер Notifly формирует из батча одно уведомление в стиле Sentry-карточки:
- Заголовок — первая ошибка (
TypeError: …, +(+N more)если ошибок несколько). - Тело (Markdown) — тэги (level · environment · release · браузер · язык), URL:строка:колонка, referrer/viewport, стектрейс первой ошибки (уже раскрытый через source maps), компактный список остальных (до 4), последние breadcrumbs (до 3), число повторений проблемы и время её первого появления.
Порог уведомлений и окружения
Заголовок раздела «Порог уведомлений и окружения»У скрипта console_errors есть две серверные настройки (в админке — поля
«Порог уведомления» и «Окружения», в API — notifyThreshold и
environments):
notifyThreshold—info,warning,errorилиfatal: уведомлять только об ошибках этого уровня и выше. Пусто — любые уровни. Ошибки ниже порога всё равно группируются в проблемы и видны на графике, но без push.environments— allowlist окружений через запятую, напримерproduction,staging. Пусто — любое окружение. Батч из окружения не из списка отбрасывается целиком: не попадает ни в проблемы, ни в графики.
Привязка к релизу
Заголовок раздела «Привязка к релизу»Задайте window.NOTIFLY_RELEASE до загрузки скрипта — значение попадёт
в поле release каждого батча:
<script> window.NOTIFLY_RELEASE = 'v2.1.0-abc1234';</script><!-- Notifly console_errors snippet here -->Куда вставлять в популярных фреймворках
Заголовок раздела «Куда вставлять в популярных фреймворках»| Фреймворк | Где размещать |
|---|---|
| Next.js (App Router) | app/layout.tsx в <head> через next/script strategy="beforeInteractive" |
| Next.js (Pages) | pages/_document.tsx в <Head> |
| React (CRA / Vite) | public/index.html в <head> перед бандлом |
| Vue / Nuxt | nuxt.config → app.head.script или app.html |
| Angular | src/index.html в <head> перед polyfills |
| Astro | src/layouts/Layout.astro в <head> |
| Electron | В renderer HTML <head> |
Source maps — раскрывание минифицированного стека
Заголовок раздела «Source maps — раскрывание минифицированного стека»Если ваш JS прошёл через минификатор (esbuild, terser, Webpack production), стектрейсы
в браузере выглядят как at f (https://app.example.com/static/js/main.abc123.js:1:12345) —
без имён функций и реальных строк. Notifly умеет на лету разворачивать такие фреймы
обратно к исходникам (TypeScript / .vue / .jsx), используя загруженные source map.
Как это работает
Заголовок раздела «Как это работает»- Соберите фронтенд с включёнными
.map-файлами (sourceMap: true). - Загрузите эти
.mapв Notifly через REST API — по одной карте на каждый.js-файл. - Укажите для каждого
.mapтот жеrelease, что прокидываете вwindow.NOTIFLY_RELEASE. - При получении ошибки Notifly находит
.mapпоrelease+ URL-префиксу + имени файла и подменяетURL:LINE:COLнаsrc/file.ts:LINE:COL— прямо в тексте уведомления.
Резолвинг — best-effort: если карта не найдена или фрейм не совпал, в уведомление попадает оригинальный (минифицированный) стек.
Загрузка через REST
Заголовок раздела «Загрузка через REST»# API-токен с правом записиcurl -H "X-Notifly-Key: <api-token>" \ -F "release=v2.1.0-abc1234" \ -F "urlPrefix=https://app.example.com/static/js/" \ -F "fileName=main.abc123.js" \ -F "file=@dist/static/js/main.abc123.js.map" \ "$NOTIFLY_URL/web-script/<scriptId>/sourcemaps"Вместо токена эта ручка — единственная в API — принимает и логин с паролем
аккаунта (HTTP Basic, curl -u "$NOTIFLY_USER:$NOTIFLY_PASSWORD"): так проще
в старых CI-скриптах. Source maps принимаются только для скриптов типа
console_errors.
Тело запроса — multipart/form-data с обязательными полями:
| Поле | Описание |
|---|---|
file | Сам .map-файл (JSON Source Map v3, до 10 MB) |
release | Версия релиза — должна совпасть с window.NOTIFLY_RELEASE |
urlPrefix | Префикс URL, по которому браузер грузит этот .js (например https://x/static/) |
fileName | Имя .js-файла без префикса (main.abc123.js), без / и \ |
При совпадении кадра по urlPrefix + fileName Notifly резолвит позицию. Поиск
кадра — по длиннейшему префиксу, так что можно держать одновременно карты
с разных доменов / CDN. Файл проверяется при загрузке: не Source Map v3 — 400,
больше 10 MB — 413; анти-XSSI префикс )]}' срезается автоматически.
Через SDK
Заголовок раздела «Через SDK»Если сборка уже ходит в Notifly из кода, загрузка — один вызов SDK с API-токеном (право записи), без basic-аутентификации:
f, _ := os.Open("dist/static/js/main.abc123.js.map")defer f.Close()
_, err := admin.UploadSourceMap(ctx, scriptID, notifly.SourceMapUpload{ Release: os.Getenv("GITHUB_SHA"), // должен совпасть с window.NOTIFLY_RELEASE URLPrefix: "https://app.example.com/static/js/", FileName: "main.abc123.js", Map: f,})with open("dist/static/js/main.abc123.js.map", "rb") as f: admin.upload_source_map(script_id, os.environ["GITHUB_SHA"], "https://app.example.com/static/js/", "main.abc123.js", f)Повторная загрузка той же пары (release, fileName) заменяет карту, а не
плодит дубли, поэтому перезапуск сборки безопасен. Размер и имя файла SDK
проверяет до отправки.
CLI-хелпер
Заголовок раздела «CLI-хелпер»Чтобы не звать curl в цикле, используйте готовый скрипт
scripts/upload-sourcemaps.py:
python3 scripts/upload-sourcemaps.py \ --api https://api.notifly.ru \ --token "$NOTIFLY_TOKEN" \ --script-id 12345 \ --release "$GITHUB_SHA" \ --url-prefix "https://app.example.com/static/js/" \ --dir ./dist/static/jsСкрипт берёт API-токен из --token / NOTIFLY_TOKEN, либо логин и пароль из
--user/--password (NOTIFLY_USER/NOTIFLY_PASSWORD). Пример GitHub
Actions — выгрузка карт после билда:
- name: Build run: npm run build
- name: Upload sourcemaps to Notifly env: NOTIFLY_TOKEN: ${{ secrets.NOTIFLY_TOKEN }} run: | python3 scripts/upload-sourcemaps.py \ --script-id ${{ vars.NOTIFLY_SCRIPT_ID }} \ --release "${{ github.sha }}" \ --url-prefix "https://app.example.com/static/js/" \ --dir ./dist/static/jsУправление и REST
Заголовок раздела «Управление и REST»| Метод и путь | Назначение |
|---|---|
GET /web-script/:id/sourcemaps | список загруженных карт |
POST /web-script/:id/sourcemaps | загрузить .map (multipart) |
DELETE /web-script/:id/sourcemaps/:smid | удалить карту (S3 + БД) |
В админке кнопка «Source maps» появляется на карточке скрипта типа
console_errors — там же можно посмотреть список, удалить устаревшие карты
или загрузить новый .map без CLI.
Безопасность и лимиты
Заголовок раздела «Безопасность и лимиты»- Карты хранятся в приватном S3-бакете Yandex Object Storage, прямого URL у них нет.
- Содержимое дедуплицируется по
sha256— повторная заливка одного и того же файла не создаёт лишних копий. - Максимальный размер одного
.map— 10 MB, не больше 500 карт на скрипт. - При удалении web-скрипта все связанные
.mapудаляются автоматически (cascade). - Резолв ограничен таймаутом 3 секунды на запрос — если карт много, лишние игнорируются, оригинальный стек всё равно попадёт в уведомление.
Триггер вручную
Заголовок раздела «Триггер вручную»Вы можете дёрнуть /script/T<token> чем угодно — этот эндпоинт публичный
и принимает GET и POST. JSON-тело необязательно: если его нет, в push
уйдёт title из настроек скрипта и текст «(web script trigger)».
# минимальноcurl -fsS "$NOTIFLY_URL/script/T7c2a8f3b1e0d4a6c8e9f" -o /dev/null
# с переопределением заголовка и текстаcurl -X POST "$NOTIFLY_URL/script/T7c2a8f3b1e0d4a6c8e9f" \ -H "Content-Type: application/json" \ -d '{"title":"Заявка №42","message":"Имя: Иван\nТелефон: +7..."}'Ответы: 200 {"ok": true} — уведомление создано; 400 — неизвестный токен или
невалидное тело; 413 — тело больше 64 KiB; 429 — исчерпана дневная квота
или слишком частые запросы; 503 — временный сбой, запрос можно повторить.
REST API
Заголовок раздела «REST API»| Метод и путь | Авторизация | Назначение |
|---|---|---|
GET /web-script | API-токен | список скриптов |
POST /web-script | API-токен (write) | создание |
PUT /web-script/:id | API-токен (write) | обновление |
DELETE /web-script/:id | API-токен (write) | удалить |
GET /web-script/:id/sourcemaps | API-токен | список source map |
POST /web-script/:id/sourcemaps | API-токен (write) или Basic | загрузить .map |
DELETE /web-script/:id/sourcemaps/:smid | API-токен (write) | удалить .map |
GET /web-script/:id/issues | API-токен | список агрегированных ошибок |
GET /web-script/:id/issue-count | API-токен | число нерешённых проблем ({"unresolved": N}) |
POST /web-script/:id/issues/:iid/resolve | API-токен (write) | отметить решённой |
POST /web-script/:id/issues/:iid/ignore | API-токен (write) | игнорировать проблему |
DELETE /web-script/:id/issues/:iid | API-токен (write) | удалить |
GET /web-script/:id/issues/:iid/breadcrumbs | API-токен | последние действия пользователя перед ошибкой |
POST /web-script/:id/issues/:iid/analyze | API-токен | AI-разбор причины (тело: lang, force) |
GET /web-script/:id/issues/:iid/analysis | API-токен | сохранённый разбор (204, если его ещё нет) |
GET /web-script/:id/series | API-токен | тайм-серия срабатываний скрипта |
GET /web-script/:id/error-series | API-токен | тайм-серия ошибок console_errors |
GET /web-script/:id/flush-stats | API-токен | распределение причин отправки батчей |
GET/POST /script/:token | публичный | триггер из браузера или скрипта |
Токены канала (в том числе расшаренного) к управляющим ручкам не пускаются —
403.
Раздел «Проблемы» на карточке скрипта console_errors группирует входящие
ошибки в дедуплицированные проблемы. Ключ группировки — тип ошибки, до пяти
верхних кадров стека (после source maps; номера строк без колонок, URL без
query и с обобщёнными id в пути) и release; если распознаваемого стека нет —
нормализованное сообщение (числа, UUID, URL заменены плейсхолдерами) и URL
страницы. Для каждой проблемы видно число повторений (и оценку с учётом
sampleRate — estimatedCount), время первого и последнего появления, образец
стека, URL и браузер; «События перед ошибкой» (breadcrumbs) хранятся ~14 дней,
сами проблемы удаляются через 90 дней без новых событий.
- Пометить решённой (
/issues/:iid/resolve) — следующее появление снова даст уведомление как регрессия. Тело{"resolved": false}открывает проблему снова. - Заглушить уведомления (
/issues/:iid/ignore) — события продолжают считаться, но уведомления по проблеме не приходят никогда.{"ignored": false}— включить обратно. - Удалить —
DELETE /web-script/:id/issues/:iid.
issue-count не учитывает решённые и заглушённые проблемы — это число для бейджа
на карточке.
AI-разбор проблемы
Заголовок раздела «AI-разбор проблемы»POST /web-script/:id/issues/:iid/analyze собирает улики (стек, breadcrumbs,
контекст страницы), отдаёт их модели и сохраняет разбор — вероятную причину и
что проверить в первую очередь:
curl -X POST "$NOTIFLY_URL/web-script/77/issues/1234/analyze" \ -H "Content-Type: application/json" \ -H "X-Notifly-Key: <api-token>" \ -d '{"lang": "ru"}'Ответ:
{ "probableCause": "…", "evidence": ["…"], "suggestedSteps": ["…"], "confidence": "medium", "model": "…", "lang": "ru", "created": "2026-09-27T10:00:00Z", "stale": false}lang — язык разбора (по умолчанию ru), confidence — high, medium или
low; в evidence и suggestedSteps — до пяти пунктов.
Разбор кэшируется по отпечатку входных данных: пока проблема не получила новых
событий и язык не менялся, повторный вызов отдаёт сохранённый результат — без
обращения к модели и без списания квоты ИИ-помощников (aiRequestsPerDay, см.
квоты). Принудительно пересчитать — {"force": true}.
Готовый разбор доступен отдельно через GET /web-script/:id/issues/:iid/analysis
(204, если его ещё нет; stale: true — после разбора у проблемы появились новые
события).
Ошибки: 422 — у проблемы нет ни стека, ни breadcrumbs, разбирать нечего;
429 — исчерпана дневная квота ИИ-запросов; 503 — ИИ не настроен; 502 —
модель не ответила или вернула некорректный результат.
Графики активности
Заголовок раздела «Графики активности»Тайм-серии принимают общие параметры ?bucket=1m|1h|1d&from=&to= (RFC3339);
по умолчанию — 1h за последние 24 часа, окно не длиннее 35 дней. Минутные
данные хранятся около суток, дневные — около месяца, поэтому для длинных окон
берите 1d.
/series— срабатывания триггерных скриптов (page_open,form_submit,button_click); дляconsole_errorsвернётся пусто./error-series— динамика ошибокconsole_errorsс разбивкой по уровням (info,warning,error,fatal); считаются все принятые события, включая ниже порога уведомлений./flush-stats— распределение причин отправки батчей (reason → count:batch,timer,pagehide,visibilitychange,manual, …): видно, какая доля батчей уходит при закрытии страницы (черезsendBeacon).
Безопасность
Заголовок раздела «Безопасность»T<token>подбирается криптостойким случайным генератором (160 бит). Он неизбежно виден в коде страницы, поэтому считайте его «публичным ключом приёма»: с ним можно только слать события в этот скрипт.- Сменить токен у существующего скрипта нельзя. Если токеном злоупотребляют —
удалите скрипт через админку или
DELETE /web-script/:idи создайте новый: запросы на старый URL будут получать400без создания уведомлений. - На каждом успешном триггере поле
lastUsedобновляется — в админке видно, если скрипт «висит» неиспользуемым.