Документация REST API
Notifly предоставляет REST API для управления каналами, клиентами, сообщениями, мониторингом, метриками и пользователями.
Все примеры используют базовый URL API https://api.notifly.ru (можно подставить через переменную $NOTIFLY_URL).
https://notifly.ru — это сайт документации, API там нет. Админка (веб-интерфейс) живёт на
https://app.notifly.ru/.
Аутентификация
Заголовок раздела «Аутентификация»Токены Notifly различаются по первой букве. Длина — 23 символа (префикс + 22).
| Тип | Префикс | Назначение |
|---|---|---|
| Ключ канала (app-токен) | A | Отправка в свой канал (POST /message, POST /ask, приёмники мониторинга); с правом чтения — ещё и чтение сообщений этого канала |
| Токен доступа к каналу | S | Ключ получателя делегированного доступа: то же, что A…, но отправка — только при праве send |
| API-токен | M | Программный доступ к аккаунту (read или read+write, скоуп по каналам), см. API-токены |
| Токен устройства | C | Сессия приложения или браузера: всё, что умеет API-токен, плюс управление устройствами, API-токенами, паролем и 2FA. Не ключ для интеграций |
| Ping-токен heartbeat | H | Только в URL /heartbeat/ping/{token} |
| Токен webhook-роутера | R | Только в URL /router/{token}/… |
Токены web-скриптов (T…) и источников метрик (M…, но это не API-токен) тоже живут только в URL
своих публичных эндпоинтов и доступа к аккаунту не дают.
Токен передаётся одним из способов (если прислано несколько, берётся первый по этому списку):
- заголовок
X-Notifly-Key; - заголовок
X-Gotify-Key(устаревший, для совместимости с клиентами Gotify); - заголовок
Authorization: Bearer …; - query-параметр
?token=— для транспортов без заголовков (WebSocket, SSE,<img>); - cookie
notifly-client-token— её ставитPOST /auth/local/loginдля браузера.
# 1. Заголовок X-Notifly-Keycurl -H "X-Notifly-Key: MtVOKLDNuD7HR9y7QkMecC5" https://api.notifly.ru/application
# 2. Query-параметрcurl "https://api.notifly.ru/application?token=CK2UDmhduKshCyz-RtqxiLx"
# 3. Bearer-токенcurl -H "Authorization: Bearer CK2UDmhduKshCyz-RtqxiLx" https://api.notifly.ru/applicationТокены канала (A…/S… с правом чтения) принимаются и на части клиентских ручек, но
видят только свой канал: GET /application вернёт один этот канал, GET /message и
GET /message/search — только его сообщения. Операции уровня аккаунта (устройства,
API-токены, мониторы, пользователь) им запрещены — 403.
Также поддерживается Basic Auth (логин/пароль) — но только на ручках, нужных клиенту, у которого токена ещё нет:
| Ручка | Зачем |
|---|---|
POST /auth/local/login | получить токен устройства по логину и паролю |
GET /current/user | проверить пару |
GET /client, GET /client/online, POST /client, POST /client/:id/reconnect | завести устройство или переподключить существующее |
POST /application | создать канал ради его app-токена |
POST /web-script/:id/sourcemaps | выгрузка source maps из CI |
На всех остальных эндпоинтах логин-пара не принимается — нужен токен. Попытки
входа парой ограничены по частоте с одного адреса, а аккаунт с неподтверждённым
email не пускается никуда. Аккаунт с включённой 2FA Basic-парой не
пройдёт (401 second factor required) — только через POST /auth/local/login и второй шаг.
В примерах ниже $TOKEN — API-токен (M…) со страницы API-токены
в админке либо токен устройства (C…) из ответа POST /auth/local/login. Там, где нужен
именно токен устройства, это сказано явно.
Информация о сервере
Заголовок раздела «Информация о сервере»Эндпоинты доступны без аутентификации.
GET /health — проверка здоровья
Заголовок раздела «GET /health — проверка здоровья»curl https://api.notifly.ru/health{"health": "green", "database": "green"}Если база недоступна — 503 с "health": "red".
GET /version — версия сервера
Заголовок раздела «GET /version — версия сервера»curl https://api.notifly.ru/version{"version": "ya-1.0.0", "commit": "...", "buildDate": "..."}GET /serverinfo — флаги сервера
Заголовок раздела «GET /serverinfo — флаги сервера»curl https://api.notifly.ru/serverinfo{"version": "ya-1.0.0", "register": false, "oidc": false}Авторизация (сессия)
Заголовок раздела «Авторизация (сессия)»POST /auth/local/login — вход по логину/паролю
Заголовок раздела «POST /auth/local/login — вход по логину/паролю»Логин и пароль передаются через Basic Auth. Создаёт устройство, возвращает его токен
(полное значение — только в этом ответе) и ставит cookie. Необязательные поля тела:
name (имя устройства) и platform.
curl -u user@example.com:пароль https://api.notifly.ru/auth/local/login \ -X POST -d "name=my-cli-client"{ "id": 1, "name": "my-cli-client", "token": "CK2UDmhduKshCyz-RtqxiLx", "user_id": 1, "platform": "web"}Если лимит устройств тарифа исчерпан, самое старое активное устройство приостанавливается,
а в ответе появляется suspended_device_id. Если у аккаунта включена 2FA, вместо
устройства приходит 401 с полем mfa — см. Двухфакторный вход.
POST /auth/logout — выход
Заголовок раздела «POST /auth/logout — выход»Ротирует токен устройства и очищает cookie. Отвечает 200 даже с недействительным токеном.
curl -H "X-Notifly-Key: CK2UDmhduKshCyz-RtqxiLx" \ https://api.notifly.ru/auth/logout -X POSTДвухфакторный вход
Заголовок раздела «Двухфакторный вход»Для аккаунта с 2FA верный пароль на POST /auth/local/login возвращает не устройство, а
401 с challenge:
{ "error": "Unauthorized", "errorCode": 401, "errorDescription": "second factor required", "mfa": { "challenge": "…", "methods": ["totp", "mobile", "recovery"], "mobileCode": "47", "expiresIn": 300 }}mobile предлагается, только если в профиле включено подтверждение входа с телефона.
Challenge живёт 5 минут и одноразовый.
| Метод и путь | Аутентификация | Описание |
|---|---|---|
POST /auth/mfa/verify | challenge в теле | Второй шаг. Тело: challenge, method (totp|recovery|mobile), code (для totp/recovery), необязательные name, platform. Успех — тот же ответ, что у логина. Неверный код — 401 invalid code, мёртвый challenge — 410 |
POST /auth/mfa/challenge | challenge в теле | Поллинг для метода mobile: {"status": "pending|approved", "mobileCode", "expiresIn"}; неизвестный challenge — 404 |
GET /auth/mfa/pending | токен устройства | Для телефона: входы, ожидающие подтверждения (ip, kind, createdAt, expiresIn) |
POST /auth/mfa/approve | токен устройства | Для телефона: подтвердить вход, тело {"code": "47"} (код с экрана входа). Нет совпадения — 404, устройство не подтверждающее — 403 |
Для метода mobile: веб показывает mobileCode, владелец вводит его в приложении
(/auth/mfa/approve), веб опрашивает /auth/mfa/challenge и после approved вызывает
/auth/mfa/verify с "method": "mobile".
curl https://api.notifly.ru/auth/mfa/verify \ -H "Content-Type: application/json" \ -d '{"challenge": "…", "method": "totp", "code": "123456", "name": "my-cli-client"}'POST /user/reset-password — запросить сброс пароля
Заголовок раздела «POST /user/reset-password — запросить сброс пароля»Публичный эндпоинт (без авторизации). Отправляет на указанный email письмо со
ссылкой для сброса пароля. Ответ всегда 200, даже если пользователя нет, —
чтобы не раскрывать, какие адреса зарегистрированы.
curl https://api.notifly.ru/user/reset-password \ -H "Content-Type: application/json" \ -d '{"email": "user@example.com"}'POST /user/reset-password/confirm — подтвердить сброс пароля
Заголовок раздела «POST /user/reset-password/confirm — подтвердить сброс пароля»Публичный эндпоинт. Принимает token из письма и новый пароль pass (от 8 символов,
не длиннее 72 байт).
curl https://api.notifly.ru/user/reset-password/confirm \ -H "Content-Type: application/json" \ -d '{"token": "<из письма>", "pass": "новый-пароль"}'Сброс пароля — сценарий восстановления после угона, поэтому вместе с паролем
аннулируются и выданные аккаунту секреты: все устройства разлогиниваются
(токены ротируются, вернуть доступ можно повторным входом или через
POST /client/:id/reconnect) и все API-токены удаляются — их придётся
выпустить заново. Ключи каналов (A…) и токены доступа к каналам (S…)
продолжают работать: они ограничены одним каналом и доступа к аккаунту не дают.
GET /user/verify — подтверждение email
Заголовок раздела «GET /user/verify — подтверждение email»Публичный эндпоинт. Открывается по ссылке из письма-подтверждения
(/user/verify?token=...) и активирует адрес пользователя.
curl "https://api.notifly.ru/user/verify?token=<из письма>"Канал (application в URL API — для совместимости с протоколом Gotify) — это источник сообщений. У каждого канала есть свой app-токен для отправки.
GET /application — список каналов
Заголовок раздела «GET /application — список каналов»Свои каналы и каналы, к которым принят делегированный доступ.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application[ { "id": 1, "token": "ApNK7NiI0ltrJf3a8BNsOiD", "name": "Мониторинг", "description": "Оповещения от системы мониторинга", "internal": false, "image": "https://…/channel-logos/1/1/9f2c….png", "defaultPriority": 5, "lastUsed": "2025-01-15T12:00:00Z", "sortKey": "a0", "tags": ["prod"], "hbTotal": 2, "hbStatus": "ok" }]Поля канала:
| Поле | Описание |
|---|---|
token | Первичный ключ канала; у расшаренного канала — собственный S…-токен получателя (пусто при праве view) |
image | Публичный URL логотипа (пусто, если не загружен) |
sortKey | Ключ ручной сортировки |
parentId | Родительский канал (дерево каналов); нет у корневого |
tags | Теги канала |
deliveryConfig | Настройки доставки; секреты адаптеров замаскированы |
shared, sharePermission, canShare | Только у расшаренных вам каналов: признак, уровень доступа (view|send) и право делиться дальше |
hbTotal, hbAlerting, hbAlertingInfo, hbPending, hbStatus | Сводка heartbeat-ов канала; hbStatus — ok|degraded|alerting|pending|none |
POST /application — создать канал
Заголовок раздела «POST /application — создать канал»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application \ -H "Content-Type: application/json" \ -d '{"name": "CI/CD", "description": "Уведомления о сборках", "defaultPriority": 5}'Поля запроса (JSON; name, description, defaultPriority, parentId, sortKey можно передать и формой):
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
name | string | ✓ | Название канала |
description | string | Описание | |
defaultPriority | integer | Приоритет по умолчанию — подставляется в сообщения без priority | |
parentId | integer | Родительский канал (дерево каналов) | |
sortKey | string | Ключ ручной сортировки | |
tags | string[] | Теги канала (до 10, [a-z0-9_-]) — используются скоупом API-токенов | |
deliveryConfig | object | Досылка непрочитанного на email/SMS/звонок/Slack/Telegram/webhook/Discord/Teams/Mattermost/PagerDuty/Opsgenie — см. Доставка |
PUT /application/{id} — обновить канал
Заголовок раздела «PUT /application/{id} — обновить канал»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1 \ -X PUT -H "Content-Type: application/json" \ -d '{"name": "CI/CD v2", "description": "Обновлённое описание"}'DELETE /application/{id} — удалить канал
Заголовок раздела «DELETE /application/{id} — удалить канал»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1 -X DELETEGET /application/{id}/status — сводный статус канала
Заголовок раздела «GET /application/{id}/status — сводный статус канала»Возвращает агрегированный статус канала (heartbeat-сводка, последняя активность).
С ?recursive=1 — по каналу и всем его потомкам.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1/statusPOST /application/{id}/delivery/test — тест доставки во внешние интеграции
Заголовок раздела «POST /application/{id}/delivery/test — тест доставки во внешние интеграции»Немедленно (в обход эскалации) отправляет тестовое уведомление через включённые способы
доставки канала (email, SMS, звонок, Slack, Telegram, webhook, Discord, Teams, Mattermost,
PagerDuty, Opsgenie) и возвращает результат по
каждому. Опциональное тело {"adapter": "slack"} ограничивает проверку одним адаптером.
Подробно — Доставка и эскалация.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1/delivery/test \ -H "Content-Type: application/json" -d '{"adapter": "telegram"}'{"results": {"telegram": {"ok": true}, "slack": {"ok": false, "error": "..."}}}Если включённых методов нет — 400 no enabled adapter to test.
GET /application/{id}/event-sources — источники событий канала
Заголовок раздела «GET /application/{id}/event-sources — источники событий канала»Всё, что пишет в канал: мониторы всех типов, heartbeat-ы, сканы портов, метрики,
web-скрипты, правила почтовых ящиков и webhook-роутера — одним списком, с текущим
статусом и временем последней проверки. Секреты источников (токены, заголовки, шаги)
в выдачу не попадают. С ?recursive=1 — включая потомков канала.
Логотип канала
Заголовок раздела «Логотип канала»| Метод и путь | Описание |
|---|---|
POST /application/{id}/image | Загрузить логотип канала (multipart/form-data, поле file) |
DELETE /application/{id}/image | Удалить логотип |
Сообщения
Заголовок раздела «Сообщения»POST /message — отправить сообщение
Заголовок раздела «POST /message — отправить сообщение»Тело — только JSON (Content-Type: application/json): form-data и urlencoded эта ручка сейчас
не принимает (400).
curl "https://api.notifly.ru/message?token=ApNK7NiI0ltrJf3a8BNsOiD" \ -H "Content-Type: application/json" \ -d '{"message": "Сборка #42 завершена", "title": "CI/CD", "priority": 5}'Поля запроса:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
message | string | ✓ | Текст сообщения |
title | string | Заголовок | |
priority | integer | Приоритет (0–10); если не указан — defaultPriority канала | |
extras | object | Дополнительные поля для клиентов (см. msgextras) |
Пример с extras (markdown-контент):
curl "https://api.notifly.ru/message?token=ApNK7NiI0ltrJf3a8BNsOiD" \ -H "Content-Type: application/json" \ -d '{ "message": "**Готово!** Подробности: [ссылка](https://example.com)", "title": "Сборка", "priority": 5, "extras": { "client::display": {"contentType": "text/markdown"} } }'Ответ:
{ "id": 123, "appid": 1, "message": "Сборка #42 завершена", "title": "CI/CD", "priority": 5, "date": "2025-06-01T10:30:00Z", "senderName": "user@example.com"}Каждое сообщение списывает одно событие дневной квоты; при исчерпании — 429 daily event quota exceeded.
Запись в служебный канал запрещена — 403.
POST /integrations/alertmanager, POST /integrations/zabbix — приём из систем мониторинга
Заголовок раздела «POST /integrations/alertmanager, POST /integrations/zabbix — приём из систем мониторинга»Нативные приёмники алертов с авторизацией app-токеном канала (заголовок
X-Notifly-Key, Authorization: Bearer или ?token=), как у POST /message.
/integrations/alertmanager— тело webhook Prometheus Alertmanager (version 4) или webhook contact point Grafana; создаёт сообщение для firing-алертов и отдельное — для resolved./integrations/zabbix— параметры media type Zabbix «Webhook» (subject,message,severity,status, …); одно сообщение.
Приоритет выводится из severity источника, каждое сообщение списывает одно
событие квоты. Ответ — {"created": N, "ids": [...]}. Настройка и маппинг —
Alertmanager, Grafana и Zabbix.
GET /message — все сообщения (с пагинацией)
Заголовок раздела «GET /message — все сообщения (с пагинацией)»Сообщения всех доступных каналов (своих и расшаренных вам), новые первыми. API-токен видит только каналы своего скоупа, токен канала — только свой канал.
curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/message?limit=20"Параметры:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | integer | 100 | Количество сообщений (1–200) |
since | integer | Курсор пагинации: вернуть сообщения с ID меньше указанного. Берётся из paging.since / paging.next предыдущей страницы |
Ответ:
{ "paging": { "size": 20, "limit": 20, "since": 4012, "next": "/message?limit=20&since=4012" }, "messages": [ { "id": 4031, "appid": 1, "message": "Текст сообщения", "title": "Заголовок", "priority": 5, "date": "2025-06-01T10:30:00Z", "read": true, "senderName": "user@example.com" } ]}paging.since и paging.next есть только когда следующая страница существует; на последней
странице их нет. В сообщении read: true — прочитано текущим пользователем (у непрочитанных поля
нет), senderName — отправитель, extras — если были переданы.
GET /application/{id}/message — сообщения канала
Заголовок раздела «GET /application/{id}/message — сообщения канала»Та же пагинация и формат ответа, что у GET /message. С ?recursive=1 — сообщения канала и
всех его потомков (получателю шары — только расшаренных ему).
curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/application/1/message?limit=50"curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/application/1/message?recursive=1"GET /message/search — полнотекстовый поиск
Заголовок раздела «GET /message/search — полнотекстовый поиск»Ищет по сообщениям пользователя. Параметр q обязателен (минимум 2 символа).
Опциональный appId ограничивает поиск одним каналом. Вместе с appId флаг
recursive=1 расширяет поиск на канал и всех его потомков (получателю шары —
только на расшаренные ему). Поддерживает пагинацию (limit, since). Токен
канала ищет только в своём канале.
curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/message/search?q=ошибка&limit=20"curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/message/search?q=deploy&appId=1"curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/message/search?q=deploy&appId=1&recursive=1"POST /message/read — отметить сообщения прочитанными
Заголовок раздела «POST /message/read — отметить сообщения прочитанными»Тело: {"ids": [1, 2, 3]} — список ID сообщений. Отметка владельца останавливает
досылку; read-only API-токен сюда не допускается.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/message/read \ -H "Content-Type: application/json" -d '{"ids": [1, 2, 3]}'POST /application/{id}/message/read — отметить весь канал прочитанным
Заголовок раздела «POST /application/{id}/message/read — отметить весь канал прочитанным»С ?recursive=1 — вместе с потомками.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1/message/read -X POSTDELETE /message — удалить все сообщения
Заголовок раздела «DELETE /message — удалить все сообщения»Недоступно API-токену с ограниченным скоупом.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/message -X DELETEDELETE /message/{id} — удалить сообщение
Заголовок раздела «DELETE /message/{id} — удалить сообщение»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/message/123 -X DELETEDELETE /application/{id}/message — удалить все сообщения канала
Заголовок раздела «DELETE /application/{id}/message — удалить все сообщения канала»С ?recursive=1 — вместе с потомками.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/application/1/message -X DELETEКлиенты
Заголовок раздела «Клиенты»Клиент — это устройство или приложение, которое получает сообщения и управляет ресурсами.
GET /client — список клиентов
Заголовок раздела «GET /client — список клиентов»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/client[ { "id": 1, "name": "firefox", "token": "C…xiLx", "lastUsed": "2025-06-01T10:00:00Z", "status": "active", "createdAt": "2025-05-20T08:00:00Z", "platform": "web", "lastIp": "203.0.113.7", "lastUserAgent": "Mozilla/5.0 …", "current": true }]token в списке — только метка, не секрет. Полное значение токена отдаётся один раз: в ответах
POST /auth/local/login, POST /client и POST /client/{id}/reconnect. status —
active|suspended|revoked, current: true — устройство, от имени которого сделан запрос.
POST /client — создать клиент
Заголовок раздела «POST /client — создать клиент»Тело: name (обязательно), platform. Ответ — созданный клиент с полным токеном. При
исчерпанном лимите устройств тарифа — 402 с errorCode: "device_limit_exceeded".
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/client \ -H "Content-Type: application/json" \ -d '{"name": "my-script"}'PUT /client/{id} — переименовать клиент
Заголовок раздела «PUT /client/{id} — переименовать клиент»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/client/1 \ -X PUT -H "Content-Type: application/json" \ -d '{"name": "renamed-client"}'DELETE /client/{id} — удалить клиент
Заголовок раздела «DELETE /client/{id} — удалить клиент»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/client/1 -X DELETEDELETE /client — удалить все устройства, кроме текущего
Заголовок раздела «DELETE /client — удалить все устройства, кроме текущего»Ответ — {"deleted": N}.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/client -X DELETEСостояние устройств и отключённые каналы
Заголовок раздела «Состояние устройств и отключённые каналы»По умолчанию устройство получает сообщения всех каналов. «Подписки» в путях ниже — это исторические имена: на деле это список отключённых (заглушённых) на устройстве каналов.
| Метод и путь | Описание |
|---|---|
GET /client/online | Список id устройств с активным WS-соединением |
POST /client/{id}/reconnect | Ротировать токен устройства; новый токен возвращается один раз |
PUT /client/{id}/status | Сменить статус, тело {"status": "active|suspended|revoked"}; revoked необратим, реактивация сверх лимита — 402 |
GET /client/{id}/activity | Журнал активности устройства (?from=&to=&type=&limit=, даты RFC3339) |
GET /client/{id}/subscriptions | Каналы, отключённые на устройстве |
PUT /client/{id}/subscriptions | Заменить список отключённых каналов, тело {"channelIds": [1, 2]} (пустой массив — включить все) |
Самообслуживание устройства (аутентификация по токену самого устройства):
| Метод и путь | Описание |
|---|---|
GET /device/me/subscriptions | Каналы, отключённые на этом устройстве |
POST /device/me/subscriptions | Отключить канал, тело {"channelId": 1} |
DELETE /device/me/subscriptions/{channel_id} | Снова включить канал |
Текущий пользователь
Заголовок раздела «Текущий пользователь»GET /current/user — информация о текущем пользователе
Заголовок раздела «GET /current/user — информация о текущем пользователе»curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/current/user{ "id": 1, "email": "user@example.com", "admin": false, "verified": true, "plan": "free", "eventCounter": 120, "messageCounter": 80, "heartbeatCounter": 30, "monitorCounter": 10, "webScriptCounter": 0, "balanceKopecks": 0, "storageBytes": 0, "image": "", "mfaEnabled": false}POST /current/user/sudo — подтвердить себя (sudo)
Заголовок раздела «POST /current/user/sudo — подтвердить себя (sudo)»Чувствительные действия (смена пароля, настройки 2FA, админские ручки) требуют свежего
подтверждения. Без него ответ — 403 с "reason": "sudo_required" и списком доступных
methods. Подтверждение открывает окно на 15 минут для этого устройства.
Только токен устройства: API-токену и токену канала окно не выдаётся (403).
| Поле | Описание |
|---|---|
method | password — если 2FA выключена; totp или recovery — если включена (пароль не принимается) |
pass | Пароль (для password) |
code | Код аутентификатора или recovery-код |
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/current/user/sudo \ -H "Content-Type: application/json" \ -d '{"method": "password", "pass": "current-password"}'{"ok": true, "method": "password", "expiresIn": 900}Неверный пароль — 400 wrong password, неверный код — 401 invalid code.
POST /current/user/password — изменить пароль
Заголовок раздела «POST /current/user/password — изменить пароль»Требует токен устройства и sudo-окно; API-токен получает 403. Текущий пароль
oldPass обязателен, новый pass — от 8 символов и не длиннее 72 байт.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/current/user/password \ -H "Content-Type: application/json" \ -d '{"pass": "new-secure-password", "oldPass": "current-password"}'Неверный oldPass — 400 с errorDescription: "wrong password". После успешной
смены остальные устройства разлогиниваются (их токены ротируются), а сессия,
из которой пришёл запрос, продолжает работать; открытые sudo-окна закрываются.
API-токены смена пароля не трогает — в отличие от сброса по письму.
Двухфакторная аутентификация (профиль)
Заголовок раздела «Двухфакторная аутентификация (профиль)»Все ручки — только токеном устройства; помеченные «sudo» требуют sudo-окна.
| Метод и путь | Описание |
|---|---|
GET /current/user/mfa | Состояние: enabled, pendingSetup, recoveryCodesRemaining, mobileConnected, mobileEnabled, approverDevices |
POST /current/user/mfa/setup | sudo. Новый секрет аутентификатора: {"secret", "uri"} (otpauth://…); 2FA уже включена — 409 |
POST /current/user/mfa/confirm | sudo. Включить 2FA первым кодом, тело {"code": "123456"}; ответ — {"recoveryCodes": [...]} |
POST /current/user/mfa/disable | sudo. Выключить 2FA |
POST /current/user/mfa/recovery-codes | sudo. Перевыпустить recovery-коды |
POST /current/user/mfa/mobile/start | sudo. Начать привязку телефона для подтверждения входов: {"challenge", "code", "expiresIn"} |
POST /current/user/mfa/mobile/confirm | Завершить привязку после того, как телефон ввёл code через /auth/mfa/approve, тело {"challenge": "…"} |
POST /current/user/mfa/mobile/disable | sudo. Выключить подтверждение входов с телефона |
DELETE /current/user/mfa/mobile/devices/{id} | sudo. Убрать устройство из подтверждающих |
Тариф, баланс и квоты
Заголовок раздела «Тариф, баланс и квоты»Подробности о тарифах и лимитах — на странице Квоты и тарифы.
| Метод и путь | Описание |
|---|---|
GET /user/quota-breakdown | Детальная разбивка расхода событий за день (?day=YYYY-MM-DD), почасовая и поминутная, плюс снимок занятого хранилища (storage) |
POST /current/user/plan | Сменить тариф, тело {"plan": "free|pro|business"}. Самостоятельно — только понизить или оставить текущий; повышение — 402 plan upgrade requires payment |
POST /current/user/topup | Пополнение баланса, тело {"amountRubles": N}. Не администратору — 402 с реквизитами оплаты (paymentMethod: "bank_transfer") |
POST /current/user/image | Загрузить аватар (multipart/form-data, поле file) |
DELETE /current/user/image | Удалить аватар |
Платёжного шлюза нет: повышение тарифа и пополнение баланса — оплата по счёту (банковский
перевод), после которой оператор переводит аккаунт на новый тариф (POST /user/{id}/plan).
curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/user/quota-breakdown?day=2026-06-23"
# Понизить тариф до freecurl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/current/user/plan \ -H "Content-Type: application/json" -d '{"plan": "free"}'Ответ POST /current/user/topup не администратору:
{ "message": "Пополните баланс переводом на указанные реквизиты", "amountRubles": 500, "paymentMethod": "bank_transfer"}Тихие часы
Заголовок раздела «Тихие часы»Подробнее — Тихие часы и дайджест.
| Метод и путь | Описание |
|---|---|
GET /current/user/quiet-hours | Текущие настройки (у нового пользователя: enabled: false, 23:00–08:00) |
PUT /current/user/quiet-hours | Сохранить; неприсланные поля сохраняют значения; ответ — сохранённый объект |
Тело: enabled, timezone (IANA), start/end (HH:MM, конец раньше начала —
через полночь), days (ISO 1=пн…7=вс, по дню начала), breakthroughPriority
(0..10), digest.
curl -X PUT -H "X-Notifly-Key: $TOKEN" -H "Content-Type: application/json" \ https://api.notifly.ru/current/user/quiet-hours \ -d '{"enabled":true,"timezone":"Europe/Moscow","start":"23:00","end":"08:00","days":[1,2,3,4,5,6,7],"breakthroughPriority":8,"digest":true}'Управление пользователями (администратор)
Заголовок раздела «Управление пользователями (администратор)»GET /user — список пользователей
Заголовок раздела «GET /user — список пользователей»Постранично, keyset по возрастанию id: limit (1–200, по умолчанию 100) и since — id
последнего пользователя предыдущей страницы.
curl -H "X-Notifly-Key: $TOKEN" "https://api.notifly.ru/user?limit=100"{ "paging": {"size": 2, "limit": 100}, "users": [ { "id": 1, "email": "admin@example.com", "admin": true, "verified": true, "plan": "business", "mfaEnabled": true }, { "id": 2, "email": "user1@example.com", "admin": false, "verified": true, "plan": "free", "mfaEnabled": false } ]}Пользователь — в том же формате, что у GET /current/user (в примере поля сокращены).
POST /user — создать пользователя
Заголовок раздела «POST /user — создать пользователя»Созданный администратором пользователь сразу подтверждён; при самостоятельной регистрации на адрес уходит письмо с подтверждением.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/user \ -H "Content-Type: application/json" \ -d '{"email": "newuser@example.com", "pass": "password123", "admin": false}'POST /user/{id} — изменить пользователя
Заголовок раздела «POST /user/{id} — изменить пользователя»Тело: email (обязательно, текущий адрес — сменить его нельзя), admin (передавайте
текущее значение: отсутствие поля означает false), pass (необязательно, новый пароль),
resetMfa (сбросить 2FA пользователя). Смена пароля администратором работает как сброс:
все устройства пользователя разлогиниваются, все его API-токены удаляются.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/user/2 \ -H "Content-Type: application/json" \ -d '{"email": "user1@example.com", "admin": false, "pass": "new-password-123"}'POST /user/{id}/plan — сменить тариф пользователю
Заголовок раздела «POST /user/{id}/plan — сменить тариф пользователю»Операторская смена тарифа, в том числе повышение после оплаты. Тело {"plan": "free|pro|business"}.
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/user/2/plan \ -H "Content-Type: application/json" -d '{"plan": "pro"}'DELETE /user/{id} — удалить пользователя
Заголовок раздела «DELETE /user/{id} — удалить пользователя»Удалить самого себя нельзя (400).
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/user/2 -X DELETEHeartbeat-мониторы
Заголовок раздела «Heartbeat-мониторы»Dead-man-switch: внешняя задача (cron, скрипт) периодически шлёт «пинг»; если пинг не приходит вовремя, Notifly присылает алерт. Подробнее — Heartbeat.
Публичный пинг (аутентификация по ping-токену H… в URL, без API-токена):
curl https://api.notifly.ru/heartbeat/ping/HrvF2iYjEnz5z8ZngHvvkX3 # GET — удобно из croncurl -X POST https://api.notifly.ru/heartbeat/ping/HrvF2iYjEnz5z8ZngHvvkX3 \ -H "Content-Type: application/json" -d '{"fail_reason": "backup failed"}'Управление (API-токен):
| Метод и путь | Описание |
|---|---|
GET /heartbeat | Список heartbeat-ов |
POST /heartbeat | Создать |
PUT /heartbeat/{id} | Обновить |
DELETE /heartbeat/{id} | Удалить |
POST /heartbeat/{id}/pause · /resume | Приостановить / возобновить |
POST /heartbeat/{id}/test-alert · /test-recovery | Тестовое алерт- / recovery-уведомление |
Мониторы
Заголовок раздела «Мониторы»Активные проверки доступности и контента. Каждый тип имеет свою страницу с деталями.
Универсальный монитор (HTTP / TCP) → /docs/monitor/
Заголовок раздела «Универсальный монитор (HTTP / TCP) → /docs/monitor/»| Метод и путь | Описание |
|---|---|
GET /monitor · POST /monitor | Список / создать |
POST /monitor/test | Проверить настройки без сохранения |
PUT /monitor/{id} · DELETE /monitor/{id} | Обновить / удалить |
POST /monitor/{id}/pause · /resume | Приостановить / возобновить |
| Метод и путь | Описание |
|---|---|
GET /http-monitor · POST /http-monitor | Список / создать |
POST /http-monitor/test | Проверить запрос |
PUT /http-monitor/{id} · DELETE /http-monitor/{id} | Обновить / удалить |
POST /http-monitor/{id}/pause · /resume | Приостановить / возобновить |
Монитор контента → /docs/content-monitor/
Заголовок раздела «Монитор контента → /docs/content-monitor/»| Метод и путь | Описание |
|---|---|
GET /content-monitor · POST /content-monitor | Список / создать |
POST /content-monitor/suggest-selector | ИИ-подбор CSS-селектора |
POST /content-monitor/test-rule | Проверить правило |
PUT /content-monitor/{id} · DELETE /content-monitor/{id} | Обновить / удалить |
POST /content-monitor/{id}/pause · /resume | Приостановить / возобновить |
| Метод и путь | Описание |
|---|---|
GET /port-monitor · POST /port-monitor | Список / создать |
POST /port-monitor/test | Проверить порт |
PUT /port-monitor/{id} · DELETE /port-monitor/{id} | Обновить / удалить |
POST /port-monitor/{id}/pause · /resume | Приостановить / возобновить |
Сканирование портов → /docs/port-scan/
Заголовок раздела «Сканирование портов → /docs/port-scan/»| Метод и путь | Описание |
|---|---|
GET /port-scan · GET /port-scan/{id} | Список / один скан |
POST /port-scan | Запустить скан |
PATCH /port-scan/{id} · DELETE /port-scan/{id} | Обновить / удалить |
POST /port-scan/{id}/cancel · /restart | Отменить / перезапустить |
POST /port-scan/{id}/to-monitor | Превратить найденный порт в монитор |
Workflow-монитор → /docs/workflow-monitor/
Заголовок раздела «Workflow-монитор → /docs/workflow-monitor/»| Метод и путь | Описание |
|---|---|
GET /workflow-monitor · POST /workflow-monitor | Список / создать |
POST /workflow-monitor/build-step | ИИ-сборка шага |
POST /workflow-monitor/test | Прогнать сценарий |
PUT /workflow-monitor/{id} · DELETE /workflow-monitor/{id} | Обновить / удалить |
POST /workflow-monitor/{id}/pause · /resume | Приостановить / возобновить |
Браузерный workflow → /docs/browser-workflow/
Заголовок раздела «Браузерный workflow → /docs/browser-workflow/»| Метод и путь | Описание |
|---|---|
GET /browser-workflow · POST /browser-workflow | Список / создать |
POST /browser-workflow/build-step | ИИ-подбор действия |
POST /browser-workflow/login | Захват cookie авторизации |
POST /browser-workflow/test-step | Проверить шаг |
PUT /browser-workflow/{id} · DELETE /browser-workflow/{id} | Обновить / удалить |
POST /browser-workflow/{id}/pause · /resume | Приостановить / возобновить |
Скриншоты браузерных проверок
Заголовок раздела «Скриншоты браузерных проверок»GET /browser-shot/{key} отдаёт JPEG-скриншот сбоя браузерного workflow или браузерного
монитора контента. key берётся из поля notifly::screenshot в extras алерт-сообщения.
Доступ — только владельцу монитора; для <img> токен можно передать в ?token=. Старые
скриншоты вычищаются ретенцией — тогда 404.
curl -H "X-Notifly-Key: $TOKEN" -o shot.jpg \ "https://api.notifly.ru/browser-shot/<значение notifly::screenshot>"Подтверждённые хосты → /docs/verified-host/
Заголовок раздела «Подтверждённые хосты → /docs/verified-host/»Подтверждение владения хостом перед сканированием/мониторингом.
| Метод и путь | Описание |
|---|---|
GET /verified-host | Список |
POST /verified-host/start · /check | Начать / проверить подтверждение |
DELETE /verified-host/{id} | Удалить |
История проверок мониторов
Заголовок раздела «История проверок мониторов»{kind} — тип монитора (monitor, http-monitor, content-monitor, port-monitor и т. д.).
| Метод и путь | Описание |
|---|---|
GET /monitor-history/{kind}/{id} | Uptime %, время отклика, агрегаты |
GET /monitor-history/{kind}/{id}/log | Подробный лог отдельных проверок |
Почтовые ящики (Email Inbox)
Заголовок раздела «Почтовые ящики (Email Inbox)»Входящее письмо на адрес ящика превращается в уведомление. Подробнее — Email Inbox.
| Метод и путь | Описание |
|---|---|
GET /email-inbox · POST /email-inbox | Список / создать ящик |
PUT /email-inbox/{id} · DELETE /email-inbox/{id} | Обновить / удалить |
GET /email-inbox/{id}/rules · POST /email-inbox/{id}/rules | Правила обработки писем |
PUT /email-inbox/{id}/rules/{rid} · DELETE /email-inbox/{id}/rules/{rid} | Обновить / удалить правило |
GET /email-inbox/event | История входящих писем |
GET /email-inbox/event/{eid} · DELETE /email-inbox/event/{eid} | Письмо / удалить |
POST /email-inbox/rule/from-event/{eid} | ИИ-подсказка правила по письму |
Web-скрипты
Заголовок раздела «Web-скрипты»JS-сниппеты для сайта: трекинг ошибок (console_errors), события и т. п. Подробнее — Web-скрипт.
Публичный ingest (аутентификация по токену в URL, отправка из браузера). GET и POST
без тела тоже работают — скрипт срабатывает со своими настройками по умолчанию:
curl -X POST https://api.notifly.ru/script/<token> \ -H "Content-Type: application/json" -d '{ ... }'curl https://api.notifly.ru/script/<token>Управление (API-токен):
| Метод и путь | Описание |
|---|---|
GET /web-script · POST /web-script | Список / создать |
PUT /web-script/{id} · DELETE /web-script/{id} | Обновить / удалить |
GET /web-script/{id}/sourcemaps · POST /web-script/{id}/sourcemaps | Source maps |
DELETE /web-script/{id}/sourcemaps/{smid} | Удалить source map |
GET /web-script/{id}/issues | Сгруппированные ошибки (issues) |
GET /web-script/{id}/issue-count | Число нерешённых issue ({"unresolved": N}) |
POST /web-script/{id}/issues/{iid}/resolve · /ignore | Пометить issue решённым / игнорируемым |
DELETE /web-script/{id}/issues/{iid} | Удалить issue |
GET /web-script/{id}/issues/{iid}/breadcrumbs | Действия пользователя перед ошибкой |
POST /web-script/{id}/issues/{iid}/analyze | AI-разбор причины (тело: lang, force) |
GET /web-script/{id}/issues/{iid}/analysis | Сохранённый разбор (204, если его нет) |
GET /web-script/{id}/series · /error-series | Тайм-серии срабатываний и ошибок (?bucket=1m|1h|1d&from=&to=) |
GET /web-script/{id}/flush-stats | Распределение причин отправки батчей |
Webhook-роутер
Заголовок раздела «Webhook-роутер»Принимает входящие вебхуки и маршрутизирует их по правилам в каналы. Это singleton на пользователя с path-based маршрутизацией. Подробнее — Webhook-роутер.
Публичный приём (аутентификация по токену R… в URL, любой путь после токена; принимается
и GET без тела):
curl -X POST https://api.notifly.ru/router/<token>/любой/путь \ -H "Content-Type: application/json" -d '{ ... }'Управление (API-токен):
| Метод и путь | Описание |
|---|---|
GET /webhook-router · PUT /webhook-router | Получить / обновить роутер |
POST /webhook-router/rotate-token | Сменить публичный токен |
GET /webhook-router/rule · POST /webhook-router/rule | Правила маршрутизации |
PUT /webhook-router/rule/{rid} · DELETE /webhook-router/rule/{rid} | Обновить / удалить правило |
GET /webhook-router/event · GET /webhook-router/event/{eid} | История событий |
DELETE /webhook-router/event/{eid} | Удалить событие |
GET /webhook-router/message · DELETE /webhook-router/message/{mid} | Маршрутизированные сообщения |
POST /webhook-router/rule/from-event/{eid} | ИИ-подсказка правила по событию |
Метрики
Заголовок раздела «Метрики»Числовые временные ряды с алертами. Подробнее — Метрики.
Публичный приём метрики (аутентификация по токену источника M… в URL — это не API-токен):
curl -X POST https://api.notifly.ru/metric/<token> \ -H "Content-Type: application/json" -d '{ ... }'Управление (API-токен):
| Метод и путь | Описание |
|---|---|
GET /metric-source · POST /metric-source | Источники метрик |
PUT /metric-source/{id} · DELETE /metric-source/{id} | Обновить / удалить источник |
GET /metric-source/{id}/metrics | Метрики источника |
PATCH /metric-source/{id}/metrics/{mid} · DELETE /metric-source/{id}/metrics/{mid} | Тип / удалить метрику |
GET /metric-source/{id}/metrics/{mid}/series | Временной ряд значений |
GET /metric-source/{id}/alerts · POST /metric-source/{id}/alerts | Алерты по метрике |
PUT /metric-source/{id}/alerts/{aid} · DELETE /metric-source/{id}/alerts/{aid} | Обновить / удалить алерт |
Делегированный доступ (Channel Shares)
Заголовок раздела «Делегированный доступ (Channel Shares)»Предоставление другим пользователям доступа к каналу по email. Подробнее — Доступ к каналам.
| Метод и путь | Описание |
|---|---|
GET /application/{id}/share · POST /application/{id}/share | Список / создать шару на канал |
PUT /share/{id} · DELETE /share/{id} | Обновить / отозвать шару |
GET /share/incoming | Шары, предоставленные мне |
GET /share/recipients | Адреса, с кем я уже делился (подсказки) |
POST /share/{id}/accept · /decline | Принять / отклонить шару |
POST /share/join | Присоединиться по токену |
POST /share/leave | Отказаться от доступа к каналу, тело {"appid": N} |
POST /share/rotate | Сменить значение своего Share-токена, тело {"appid": N} |
Машинные ключи канала
Заголовок раздела «Машинные ключи канала»Несколько ключей на канал с раздельными правами, мягким отзывом и ротацией. Доступно только владельцу канала.
| Метод и путь | Описание |
|---|---|
GET /application/{id}/token · POST /application/{id}/token | Список / выдать ключ. Body: name, canRead, canWrite, note, expiresAt (unix ms, 0 — бессрочно) |
PUT /token/{id} | Изменить права, метку и срок |
DELETE /token/{id} | Отозвать ключ (повторный вызов удаляет запись; первичный ключ канала → 409) |
POST /token/{id}/rotate | Сменить значение, сохранив id и права |
Публичные статус-страницы
Заголовок раздела «Публичные статус-страницы»Публичная страница со статусом и аптаймом мониторов канала. Подробнее — Статус-страницы.
Управление (API-токен, только владелец канала):
| Метод и путь | Описание |
|---|---|
GET /status-page | Список своих статус-страниц |
POST /status-page | Создать. Body: appid, slug, title, description, enabled, lang (ru|en), brandingHidden |
PUT /status-page/{id} | Обновить (тот же payload) |
DELETE /status-page/{id} | Удалить |
Публичные эндпоинты (без авторизации):
| Метод и путь | Описание |
|---|---|
GET /status/{slug} | HTML-страница статуса |
GET /status/{slug}/summary | Тот же срез в JSON: overall, overallUptime90d, services[], incidents[] |
POST /status/{slug}/subscribe | Подписка по email (double opt-in), тело {"email": "..."} |
GET /status-subscribe/verify?token=… | Подтвердить подписку (ссылка из письма) |
GET /status-subscribe/unsub?token=… | Отписаться (ссылка из письма) |
curl -H "X-Notifly-Key: $TOKEN" https://api.notifly.ru/status-page \ -H "Content-Type: application/json" \ -d '{"appid": 1, "slug": "acme-status", "title": "Статус ACME", "enabled": true, "lang": "ru"}'
curl https://api.notifly.ru/status/acme-status/summaryКоды: 400 — некорректный slug/язык или чужой канал, 403 — лимит тарифа или премиум-поле
не по плану, 404 — страница не найдена или не опубликована, 409 — slug занят.
Окна обслуживания
Заголовок раздела «Окна обслуживания»Плановые работы: мониторы охвата не алертят, сообщения не эскалируются и приходят беззвучно, статус-страница показывает «Плановые работы». Подробнее — Окна обслуживания.
| Метод и путь | Описание |
|---|---|
GET /maintenance-window | Список своих окон |
POST /maintenance-window | Создать |
GET /maintenance-window/{id} | Одно окно |
PUT /maintenance-window/{id} | Заменить поля |
DELETE /maintenance-window/{id} | Удалить (204) |
Тело: name, channelIds[], includeSubtree, monitors[] ({"kind","id"}), schedule
(once — startsAt/endsAt; weekly — timezone, days, start, end), enabled. В ответе
дополнительно active, nextStart, nextEnd, coveredChannelIds.
curl -X POST -H "X-Notifly-Key: $TOKEN" -H "Content-Type: application/json" \ https://api.notifly.ru/maintenance-window \ -d '{"name":"Релиз","channelIds":[12],"includeSubtree":true,"monitors":[],"schedule":"once","startsAt":"2026-10-02T23:00:00Z","endsAt":"2026-10-03T01:00:00Z","enabled":true}'Коды: 400 — ошибка валидации или чужой канал/монитор, 403 — лимит или неподходящий
API-токен, 404 — окна нет или оно чужое.
API-токены
Заголовок раздела «API-токены»Программные ключи аккаунта (M…) для SDK, CLI и MCP.
Выпускаются из админки; подробности — на странице API-токены.
Управлять ими можно только токеном устройства: сам API-токен к этим ручкам не
допускается (403).
| Метод и путь | Описание |
|---|---|
GET /api-token | Список; поле token — метка M…ab3d, не секрет |
POST /api-token | Выпустить; единственный ответ с полным значением |
PUT /api-token/{id} | Изменить название, доступ, скоуп, срок |
POST /api-token/{id}/rotate | Перевыпустить: новое значение, прежние настройки |
DELETE /api-token/{id} | Удалить |
Тело POST/PUT:
| Поле | Тип | Описание |
|---|---|---|
name | string | Название (обязательно) |
access | string | read или write (обязательно) |
appIds | int[] | Разрешённые каналы по id |
appTags | string[] | Разрешённые каналы по тегам; пустые appIds и appTags — все каналы. В PUT отсутствие поля — не менять |
expiresAt | string | Срок действия, RFC3339, в будущем; в PUT отсутствие поля — не менять |
curl -H "X-Notifly-Key: $DEVICE_TOKEN" https://api.notifly.ru/api-token \ -H "Content-Type: application/json" \ -d '{"name": "ci", "access": "write", "appTags": ["prod"], "expiresAt": "2027-01-01T00:00:00Z"}'Вопросы канала (Ask)
Заголовок раздела «Вопросы канала (Ask)»Интерактивные вопросы: канал спрашивает — пользователь отвечает из интерфейса. Подробнее — Ask.
Отправка вопроса использует app-токен:
| Метод и путь | Аутентификация | Описание |
|---|---|---|
POST /ask | app-токен | Задать вопрос от имени канала |
GET /ask/pending-answers | app-токен | Забрать готовые ответы |
POST /ask/ack | app-токен | Подтвердить получение ответов |
GET /ask-question/{id} | app-токен | Узнать ответ на конкретный вопрос (истёк или отменён — 410) |
POST /ask-question/{id}/answer | API-токен | Ответить на вопрос из UI |
DELETE /ask-question/{id} | API-токен | Отменить вопрос |
POST /message/{id}/answer | API-токен | Ответить на вопрос из сообщения |
POST /ask-question/{id}/extend | токен устройства, API или канала | Продлить срок ответа, тело {"timeout_sec": 1…86400}; токен канала — с правом записи |
GET /a/answer?token=… | подписанная ссылка | Ответ по кнопке из письма или Telegram |
GET /m/read?token=… | подписанная ссылка | Отметить сообщение прочитанным (останавливает досылку) |
ИИ-ассистент
Заголовок раздела «ИИ-ассистент»Чат-копайлот для онбординга и помощи. Подробнее — Ассистент.
| Метод и путь | Описание |
|---|---|
GET /assistant/threads | Список бесед |
GET /assistant/threads/{id}/messages | История сообщений беседы |
DELETE /assistant/threads/{id} | Удалить беседу |
POST /assistant/chat | Отправить сообщение ассистенту |
GET /assistant/insights | Проактивные рекомендации по аккаунту (?polish=1, ?refresh=1, ?lang=) |
Поток сообщений в реальном времени
Заголовок раздела «Поток сообщений в реальном времени»Есть два независимых канала live-обновлений. Подробнее — на странице WebSocket.
WebSocket (/ws)
Заголовок раздела «WebSocket (/ws)»Основной канал доставки push-сообщений в реальном времени. Подключение — по токену
в query-параметре token (обычно токен устройства; другие варианты — на странице
WebSocket):
# С помощью wscatwscat -c "wss://api.notifly.ru/ws?token=CK2UDmhduKshCyz-RtqxiLx"const ws = new WebSocket('wss://api.notifly.ru/ws?token=CK2UDmhduKshCyz-RtqxiLx');ws.onmessage = (event) => { const msg = JSON.parse(event.data); console.log(`[${msg.title}] ${msg.message} (приоритет: ${msg.priority})`);};Каждое входящее событие — JSON-объект Message:
{ "id": 124, "appid": 1, "message": "Новое сообщение", "title": "Заголовок", "priority": 5, "date": "2025-06-01T10:31:00Z"}SSE (/stream)
Заголовок раздела «SSE (/stream)»Отдельный эндпоинт Server-Sent Events (GET /stream, Content-Type: text/event-stream)
для live-обновления интерфейсов: он сообщает, что что-то изменилось, а сами сообщения приходят
по WebSocket. Сервер шлёт только именованные события — connected,
channel:status_changed, share:changed (данные — {"appid": N}) — и раз в 25 секунд
keepalive-комментарий. Обработчик onmessage их не получает: подписывайтесь через
addEventListener.
Аутентификация — токен в ?token= либо cookie сессии на странице того же сайта. Для
cross-origin запросов cookie не отправится (withCredentials работает только для
origin-ов из серверной настройки CORS_ALLOWED_ORIGINS), поэтому снаружи используйте ?token=.
const es = new EventSource('https://api.notifly.ru/stream?token=CK2UDmhduKshCyz-RtqxiLx');es.addEventListener('connected', () => console.log('подключено'));es.addEventListener('channel:status_changed', (e) => { console.log('статус канала изменился', JSON.parse(e.data).appid);});es.addEventListener('share:changed', (e) => { console.log('изменился доступ к каналу', JSON.parse(e.data).appid);});На развёртываниях в AWS /stream недоступен и отвечает 503 — используйте WebSocket.
Примеры на разных языках
Заголовок раздела «Примеры на разных языках»Сообщения отправляются только JSON-телом.
import requests
API = "https://api.notifly.ru"
# Отправить сообщение (токен канала)requests.post(f"{API}/message", params={"token": "ApNK7NiI0ltrJf3a8BNsOiD"}, json={ "title": "Бэкап", "message": "Резервное копирование завершено", "priority": 2,})
# Получить сообщения (API-токен)resp = requests.get(f"{API}/message", headers={"X-Notifly-Key": "MtVOKLDNuD7HR9y7QkMecC5"})for msg in resp.json()["messages"]: print(f"[{msg['title']}] {msg['message']}")package main
import ( "bytes" "encoding/json" "net/http")
func main() { body, _ := json.Marshal(map[string]any{ "title": "Deploy", "message": "Версия 2.0 развёрнута", }) http.Post("https://api.notifly.ru/message?token=ApNK7NiI0ltrJf3a8BNsOiD", "application/json", bytes.NewReader(body))}JavaScript (Node.js)
Заголовок раздела «JavaScript (Node.js)»// Отправить сообщениеconst resp = await fetch('https://api.notifly.ru/message?token=ApNK7NiI0ltrJf3a8BNsOiD', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ title: 'CI', message: 'Тесты пройдены', priority: 3, }),});console.log(await resp.json());PowerShell
Заголовок раздела «PowerShell»# Отправить сообщение$body = @{ title = "Отчёт" message = "Ежедневный отчёт сгенерирован" priority = 1} | ConvertTo-JsonInvoke-RestMethod -Uri "https://api.notifly.ru/message?token=ApNK7NiI0ltrJf3a8BNsOiD" ` -Method POST -ContentType "application/json; charset=utf-8" -Body $bodyКоды ответов
Заголовок раздела «Коды ответов»| Код | Значение |
|---|---|
200 | Успешно |
204 | Успешно, тела нет (например, удаление окна обслуживания) |
400 | Некорректный запрос (неверные параметры, неверный пароль при переспросе) |
401 | Не авторизован (отсутствует или невалидный токен, нужен второй фактор, неверный код 2FA) |
402 | Нужна оплата: повышение тарифа, пополнение баланса, лимит устройств тарифа |
403 | Запрещено: недостаточно прав, неподходящий тип токена, нужен sudo ("reason": "sudo_required"), лимит тарифа |
404 | Ресурс не найден (в том числе чужой) |
409 | Конфликт: slug занят, вопрос уже не ожидает ответа, 2FA уже включена, отзыв первичного ключа канала |
410 | Больше не действует: вопрос истёк или отменён, MFA-challenge истёк или использован |
429 | Слишком много запросов: исчерпана дневная квота событий (daily event quota exceeded) или сработал rate limit (заголовок Retry-After) |
503 | Временно недоступно: /health при недоступной базе, /stream на AWS |