REST API Documentation
Notifly provides a REST API for managing channels, clients, messages, monitoring, metrics, and users.
All examples use the base URL https://notifly.ru (you can substitute it using the $NOTIFLY_URL variable).
The admin UI (web interface) lives at https://app.notifly.ru/.
Authentication
Section titled “Authentication”Notifly uses three types of tokens:
| Тип | Префикс | Назначение |
|---|---|---|
| App-токен | A | Только отправка сообщений (POST /message, POST /ask) |
| Client-токен | C | Управление ресурсами и получение сообщений |
| MCP-код | M | Машинный доступ (read или read+write), см. MCP |
The token can be passed in three ways:
# 1. Header X-Notifly-Keycurl -H "X-Notifly-Key: CaQw5lL_L.yiRbN" https://notifly.ru/application
# 2. Query parametercurl "https://notifly.ru/application?token=CaQw5lL_L.yiRbN"
# 3. Bearer tokencurl -H "Authorization: Bearer CaQw5lL_L.yiRbN" https://notifly.ru/applicationBasic Auth (username/password) is also supported wherever a client token is accepted.
Server information
Section titled “Server information”Endpoints are available without authentication.
GET /health — health check
Section titled “GET /health — health check”curl https://host/health{"health": "green", "database": "green"}GET /version — server version
Section titled “GET /version — server version”curl https://host/version{"version": "ya-1.0.0", "commit": "...", "buildDate": "..."}GET /serverinfo — server flags
Section titled “GET /serverinfo — server flags”curl https://host/serverinfo{"version": "ya-1.0.0", "register": false, "oidc": false}Authorization (session)
Section titled “Authorization (session)”POST /auth/local/login — login with username/password
Section titled “POST /auth/local/login — login with username/password”Creates a client session. Returns a client token and sets a cookie.
curl -u admin:admin https://host/auth/local/login \ -X POST -d "name=my-cli-client"{ "id": 1, "name": "my-cli-client", "token": "CaQw5lL_L.yiRbN", "user_id": 1, "platform": "web"}POST /auth/logout — logout
Section titled “POST /auth/logout — logout”curl -H "X-Notifly-Key: CaQw5lL_L.yiRbN" \ https://host/auth/logout -X POSTPOST /user/reset-password — request password reset
Section titled “POST /user/reset-password — request password reset”Public endpoint (no authentication). Sends an email to the specified address with a password reset link. The response is always 200, even if the user does not exist — this avoids revealing which addresses are registered.
curl https://host/user/reset-password \ -H "Content-Type: application/json" \ -d '{"email": "user@example.com"}'POST /user/reset-password/confirm — confirm password reset
Section titled “POST /user/reset-password/confirm — confirm password reset”Public endpoint. Accepts the token from the email and a new password pass.
curl https://host/user/reset-password/confirm \ -H "Content-Type: application/json" \ -d '{"token": "<из письма>", "pass": "новый-пароль"}'GET /user/verify — email verification
Section titled “GET /user/verify — email verification”Public endpoint. Opened via a link from the verification email (/user/verify?token=...) and activates the user’s address.
curl "https://host/user/verify?token=<из письма>"Channels
Section titled “Channels”A channel (application in the API URL — for compatibility with the Gotify protocol) is a source of messages. Each channel has its own app token for sending.
GET /application — list of channels
Section titled “GET /application — list of channels”curl -u admin:admin https://host/application[ { "id": 1, "token": "AGdjfk_L.dKe8q", "name": "Мониторинг", "description": "Оповещения от системы мониторинга", "internal": false, "image": "image/appicon/1.png", "defaultPriority": 5, "lastUsed": "2025-01-15T12:00:00Z" }]POST /application — create a channel
Section titled “POST /application — create a channel”curl -u admin:admin https://host/application \ -H "Content-Type: application/json" \ -d '{"name": "CI/CD", "description": "Уведомления о сборках", "defaultPriority": 5}'Request fields:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
name | string | ✓ | Channel name |
description | string | Description | |
defaultPriority | integer | Default priority |
PUT /application/{id} — update a channel
Section titled “PUT /application/{id} — update a channel”curl -u admin:admin https://host/application/1 \ -X PUT -H "Content-Type: application/json" \ -d '{"name": "CI/CD v2", "description": "Обновлённое описание"}'DELETE /application/{id} — delete a channel
Section titled “DELETE /application/{id} — delete a channel”curl -u admin:admin https://host/application/1 -X DELETEGET /application/{id}/status — aggregated channel status
Section titled “GET /application/{id}/status — aggregated channel status”Returns the aggregated status of the channel (heartbeat summary, last activity).
curl -u admin:admin https://host/application/1/statusPOST /application/{id}/delivery/test — test delivery to external integrations
Section titled “POST /application/{id}/delivery/test — test delivery to external integrations”Immediately (bypassing escalation) sends a test notification through the channel’s enabled outgoing adapters (Slack, Telegram, webhook) and returns the result for each. An optional body {"adapter": "slack"} limits the check to a single adapter.
curl -u admin:admin https://host/application/1/delivery/test \ -H "Content-Type: application/json" -d '{"adapter": "telegram"}'{"results": {"telegram": {"ok": true}, "slack": {"ok": false, "error": "..."}}}Messages
Section titled “Messages”POST /message — send a message
Section titled “POST /message — send a message”curl "https://host/message?token=AGdjfk_L.dKe8q" \ -H "Content-Type: application/json" \ -d '{"message": "Сборка #42 завершена", "title": "CI/CD", "priority": 5}'Or via form-data:
curl "https://host/message?token=AGdjfk_L.dKe8q" \ -F "title=CI/CD" -F "message=Сборка #42 завершена" -F "priority=5"Request fields:
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
message | string | ✓ | Message text |
title | string | Title | |
priority | integer | Priority (0–10) | |
extras | object | Additional fields for clients (see. msgextras) |
Example with extras (markdown content):
curl "https://host/message?token=AGdjfk_L.dKe8q" \ -H "Content-Type: application/json" \ -d '{ "message": "**Готово!** Подробности: [ссылка](https://example.com)", "title": "Сборка", "priority": 5, "extras": { "client::display": {"contentType": "text/markdown"} } }'Response:
{ "id": 123, "appid": 1, "message": "Сборка #42 завершена", "title": "CI/CD", "priority": 5, "extras": {}, "date": "2025-06-01T10:30:00Z"}GET /message — all messages (with pagination)
Section titled “GET /message — all messages (with pagination)”curl -u admin:admin "https://host/message?limit=20"Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
limit | integer | 100 | Number of messages (1–200) |
since | integer | Pagination cursor: return messages older (with ID less) than the specified. Taken from paging.next of the previous page |
Response:
{ "paging": { "size": 20, "limit": 20, "since": 0, "next": "https://host/message?limit=20&since=20" }, "messages": [ { "id": 1, "appid": 1, "message": "Текст сообщения", "title": "Заголовок", "priority": 5, "extras": {}, "date": "2025-06-01T10:30:00Z" } ]}GET /application/{id}/message — channel messages
Section titled “GET /application/{id}/message — channel messages”curl -u admin:admin "https://host/application/1/message?limit=50"GET /message/search — full-text search
Section titled “GET /message/search — full-text search”Searches the user’s messages. The q parameter is required (minimum 2 characters).
Optional appId limits the search to a single channel. Supports pagination (limit, since).
curl -u admin:admin "https://host/message/search?q=ошибка&limit=20"curl -u admin:admin "https://host/message/search?q=deploy&appId=1"POST /message/read — mark messages as read
Section titled “POST /message/read — mark messages as read”Body: {"ids": [1, 2, 3]} — list of message IDs.
curl -u admin:admin https://host/message/read \ -H "Content-Type: application/json" -d '{"ids": [1, 2, 3]}'POST /application/{id}/message/read — mark entire channel as read
Section titled “POST /application/{id}/message/read — mark entire channel as read”curl -u admin:admin https://host/application/1/message/read -X POSTDELETE /message — delete all messages
Section titled “DELETE /message — delete all messages”curl -u admin:admin https://host/message -X DELETEDELETE /message/{id} — delete a message
Section titled “DELETE /message/{id} — delete a message”curl -u admin:admin https://host/message/123 -X DELETEDELETE /application/{id}/message — delete all messages in a channel
Section titled “DELETE /application/{id}/message — delete all messages in a channel”curl -u admin:admin https://host/application/1/message -X DELETEClients
Section titled “Clients”A client is a device or application that receives messages and manages resources.
GET /client — list of clients
Section titled “GET /client — list of clients”curl -u admin:admin https://host/client[ { "id": 1, "name": "firefox", "token": "CaQw5lL_L.yiRbN", "lastUsed": "2025-06-01T10:00:00Z" }]POST /client — create a client
Section titled “POST /client — create a client”curl -u admin:admin https://host/client \ -H "Content-Type: application/json" \ -d '{"name": "my-script"}'PUT /client/{id} — update a client
Section titled “PUT /client/{id} — update a client”curl -u admin:admin https://host/client/1 \ -X PUT -H "Content-Type: application/json" \ -d '{"name": "renamed-client"}'DELETE /client/{id} — delete a client
Section titled “DELETE /client/{id} — delete a client”curl -u admin:admin https://host/client/1 -X DELETEDevice status and subscriptions
Section titled “Device status and subscriptions”| Метод и путь | Описание |
|---|---|
GET /client/online | List of client tokens with an active WS connection |
PUT /client/{id}/status | Change device status, body {"status": "active|suspended|revoked"} |
GET /client/{id}/activity | Device activity log (?from=&to=&type=&limit=) |
GET /client/{id}/subscriptions | Device subscriptions to channels |
PUT /client/{id}/subscriptions | Bulk replace subscriptions, body {"channelIds": [1, 2]} |
Device self-service (authentication using the device’s device token):
| Метод и путь | Описание |
|---|---|
GET /device/me/subscriptions | Own channel subscriptions |
POST /device/me/subscriptions | Subscribe, body {"channelId": 1} |
DELETE /device/me/subscriptions/{channel_id} | Unsubscribe from a channel |
Current user
Section titled “Current user”GET /current/user — current user information
Section titled “GET /current/user — current user information”curl -u admin:admin https://host/current/user{"id": 1, "email": "admin", "admin": true, "verified": true, "plan": "free", "balanceKopecks": 0}POST /current/user/password — change password
Section titled “POST /current/user/password — change password”curl -u admin:admin https://host/current/user/password \ -H "Content-Type: application/json" \ -d '{"pass": "new-secure-password"}'Plan, balance and quotas
Section titled “Plan, balance and quotas”Details about plans and limits are on the Quotas and tariffs page.
| Метод и путь | Описание |
|---|---|
GET /user/quota-breakdown | Detailed breakdown of event consumption per day (?day=YYYY-MM-DD), hourly and per-minute |
POST /current/user/plan | Change plan, body {"plan": "free|pro|business"} |
POST /current/user/topup | Top up balance, body {"amountRubles": N} |
curl -u admin:admin "https://host/user/quota-breakdown?day=2026-06-23"curl -u admin:admin https://host/current/user/plan \ -H "Content-Type: application/json" -d '{"plan": "pro"}'User management (administrator)
Section titled “User management (administrator)”GET /user — list of users
Section titled “GET /user — list of users”curl -u admin:admin https://host/user[ {"id": 1, "email": "admin", "admin": true, "verified": true, "plan": "free"}, {"id": 2, "email": "user1@example.com", "admin": false, "verified": true, "plan": "free"}]POST /user — create a user
Section titled “POST /user — create a user”curl -u admin:admin https://host/user \ -H "Content-Type: application/json" \ -d '{"email": "newuser@example.com", "pass": "password123", "admin": false}'DELETE /user/{id} — delete a user
Section titled “DELETE /user/{id} — delete a user”curl -u admin:admin https://host/user/2 -X DELETEHeartbeat monitors
Section titled “Heartbeat monitors”Dead-man-switch: an external task (cron, script) periodically sends a “ping”; if a ping doesn’t arrive on time, Notifly sends an alert. More details — Heartbeat.
Public ping (authentication by ping token H… in the URL, without a client token):
curl https://host/heartbeat/ping/HxxxxxxxxToken # GET — convenient from croncurl -X POST https://host/heartbeat/ping/HxxxxxxxxToken \ -H "Content-Type: application/json" -d '{"fail_reason": "backup failed"}'Management (client token):
| Метод и путь | Описание |
|---|---|
GET /heartbeat | List of heartbeats |
POST /heartbeat | Create |
PUT /heartbeat/{id} | Update |
DELETE /heartbeat/{id} | Delete |
POST /heartbeat/{id}/pause · /resume | Pause / resume |
POST /heartbeat/{id}/test-alert · /test-recovery | Test alert / recovery notification |
Monitors
Section titled “Monitors”Active availability and content checks. Each type has its own page with details.
Generic monitor (HTTP / TCP) → /docs/monitor/
Section titled “Generic monitor (HTTP / TCP) → /docs/monitor/”| Метод и путь | Описание |
|---|---|
GET /monitor · POST /monitor | List / create |
POST /monitor/test | Test configuration without saving |
PUT /monitor/{id} · DELETE /monitor/{id} | Update / delete |
POST /monitor/{id}/pause · /resume | Pause / resume |
| Метод и путь | Описание |
|---|---|
GET /http-monitor · POST /http-monitor | List / create |
POST /http-monitor/test | Test request |
PUT /http-monitor/{id} · DELETE /http-monitor/{id} | Update / delete |
POST /http-monitor/{id}/pause · /resume | Pause / resume |
| Метод и путь | Описание |
|---|---|
GET /content-monitor · POST /content-monitor | List / create |
POST /content-monitor/suggest-selector | AI-assisted CSS selector suggestion |
POST /content-monitor/test-rule | Test a rule |
PUT /content-monitor/{id} · DELETE /content-monitor/{id} | Update / delete |
POST /content-monitor/{id}/pause · /resume | Pause / resume |
| Метод и путь | Описание |
|---|---|
GET /port-monitor · POST /port-monitor | List / create |
POST /port-monitor/test | Test a port |
PUT /port-monitor/{id} · DELETE /port-monitor/{id} | Update / delete |
POST /port-monitor/{id}/pause · /resume | Pause / resume |
| Метод и путь | Описание |
|---|---|
GET /port-scan · GET /port-scan/{id} | List / single scan |
POST /port-scan | Start a scan |
PATCH /port-scan/{id} · DELETE /port-scan/{id} | Update / delete |
POST /port-scan/{id}/cancel · /restart | Cancel / restart |
POST /port-scan/{id}/to-monitor | Convert a found port into a monitor |
Workflow monitor → /docs/workflow-monitor/
Section titled “Workflow monitor → /docs/workflow-monitor/”| Метод и путь | Описание |
|---|---|
GET /workflow-monitor · POST /workflow-monitor | List / create |
POST /workflow-monitor/build-step | AI build step |
POST /workflow-monitor/test | Run a scenario |
PUT /workflow-monitor/{id} · DELETE /workflow-monitor/{id} | Update / delete |
POST /workflow-monitor/{id}/pause · /resume | Pause / resume |
Browser workflow → /docs/browser-workflow/
Section titled “Browser workflow → /docs/browser-workflow/”| Метод и путь | Описание |
|---|---|
GET /browser-workflow · POST /browser-workflow | List / create |
POST /browser-workflow/build-step | AI-assisted action suggestion |
POST /browser-workflow/login | Capture authorization cookie |
POST /browser-workflow/test-step | Test a step |
PUT /browser-workflow/{id} · DELETE /browser-workflow/{id} | Update / delete |
POST /browser-workflow/{id}/pause · /resume | Pause / resume |
Host ownership verification before scanning/monitoring.
| Метод и путь | Описание |
|---|---|
GET /verified-host | List |
POST /verified-host/start · /check | Start / check verification |
DELETE /verified-host/{id} | Delete |
Monitor check history
Section titled “Monitor check history”{kind} — monitor type (monitor, http-monitor, content-monitor, port-monitor, etc.).
| Метод и путь | Описание |
|---|---|
GET /monitor-history/{kind}/{id} | Uptime %, response time, aggregates |
GET /monitor-history/{kind}/{id}/log | Detailed log of individual checks |
Email inbox (Email Inbox)
Section titled “Email inbox (Email Inbox)”An incoming email to the inbox address is turned into a notification. More details — Email Inbox.
| Метод и путь | Описание |
|---|---|
GET /email-inbox · POST /email-inbox | List / create inbox |
PUT /email-inbox/{id} · DELETE /email-inbox/{id} | Update / delete |
GET /email-inbox/{id}/rules · POST /email-inbox/{id}/rules | Email processing rules |
PUT /email-inbox/{id}/rules/{rid} · DELETE /email-inbox/{id}/rules/{rid} | Update / delete rule |
GET /email-inbox/event | Incoming email history |
GET /email-inbox/event/{eid} · DELETE /email-inbox/event/{eid} | Email / delete |
POST /email-inbox/rule/from-event/{eid} | AI suggestion for rule from an email |
Web scripts
Section titled “Web scripts”JS snippets for the website: error tracking (console_errors), events, etc. More details — Web script.
Public ingest (authentication by token in URL, sending from the browser):
curl -X POST https://host/script/<token> \ -H "Content-Type: application/json" -d '{ ... }'Management (client token):
| Метод и путь | Описание |
|---|---|
GET /web-script · POST /web-script | List / create |
PUT /web-script/{id} · DELETE /web-script/{id} | Update / delete |
GET /web-script/{id}/sourcemaps · POST /web-script/{id}/sourcemaps | Source maps |
DELETE /web-script/{id}/sourcemaps/{smid} | Delete source map |
GET /web-script/{id}/issues | Grouped errors (issues) |
POST /web-script/{id}/issues/{iid}/resolve | Mark issue as resolved |
DELETE /web-script/{id}/issues/{iid} | Delete issue |
Webhook router
Section titled “Webhook router”Accepts incoming webhooks and routes them to channels according to rules. It’s a per-user singleton with path-based routing. More details — Webhook router.
Public endpoint (authentication by token in URL, any path after the token):
curl -X POST https://host/router/<token>/любой/путь \ -H "Content-Type: application/json" -d '{ ... }'Management (client token):
| Метод и путь | Описание |
|---|---|
GET /webhook-router · PUT /webhook-router | Get / update router |
POST /webhook-router/rotate-token | Rotate public token |
GET /webhook-router/rule · POST /webhook-router/rule | Routing rules |
PUT /webhook-router/rule/{rid} · DELETE /webhook-router/rule/{rid} | Update / delete rule |
GET /webhook-router/event · GET /webhook-router/event/{eid} | Event history |
DELETE /webhook-router/event/{eid} | Delete event |
GET /webhook-router/message · DELETE /webhook-router/message/{mid} | Routed messages |
POST /webhook-router/rule/from-event/{eid} | AI suggestion for rule from an event |
Metrics
Section titled “Metrics”Numeric time series with alerts. More details — Metrics.
Public metric ingest (authentication by token M… in URL):
curl -X POST https://host/metric/<token> \ -H "Content-Type: application/json" -d '{ ... }'Management (client token):
| Метод и путь | Описание |
|---|---|
GET /metric-source · POST /metric-source | Metric sources |
PUT /metric-source/{id} · DELETE /metric-source/{id} | Update / delete source |
GET /metric-source/{id}/metrics | Source metrics |
PATCH /metric-source/{id}/metrics/{mid} · DELETE /metric-source/{id}/metrics/{mid} | Update / delete metric |
GET /metric-source/{id}/metrics/{mid}/series | Time series of values |
GET /metric-source/{id}/alerts · POST /metric-source/{id}/alerts | Metric alerts |
PUT /metric-source/{id}/alerts/{aid} · DELETE /metric-source/{id}/alerts/{aid} | Update / delete alert |
Delegated access (Channel Shares)
Section titled “Delegated access (Channel Shares)”Granting other users access to a channel by email. More details — Channel access.
| Метод и путь | Описание |
|---|---|
GET /application/{id}/share · POST /application/{id}/share | List / create a share on a channel |
PUT /share/{id} · DELETE /share/{id} | Update / revoke a share |
GET /share/incoming | Shares granted to me |
GET /share/recipients | Addresses I’ve already shared with (hints) |
POST /share/{id}/accept · /decline | Accept / decline a share |
POST /share/join | Join by token |
MCP tokens
Section titled “MCP tokens”Machine access tokens (M…) for integration via MCP. Generated from the admin UI.
| Метод и путь | Описание |
|---|---|
GET /mcp/token · POST /mcp/token | List / create token |
PUT /mcp/token/{id} · DELETE /mcp/token/{id} | Update / delete token |
Channel questions (Ask)
Section titled “Channel questions (Ask)”Interactive questions: the channel asks — the user answers from the interface. More details — Ask.
Sending a question uses an app token:
| Метод и путь | Аутентификация | Описание |
|---|---|---|
POST /ask | app-токен | Ask a question on behalf of a channel |
GET /ask/pending-answers | app-токен | Fetch ready answers |
POST /ask/ack | app-токен | Acknowledge receipt of answers |
GET /ask-question/{id} | app-токен | Get the answer to a specific question |
POST /ask-question/{id}/answer | client-токен | Answer a question from the UI |
DELETE /ask-question/{id} | client-токен | Cancel a question |
POST /message/{id}/answer | client-токен | Answer a question from a message |
AI assistant
Section titled “AI assistant”Chat co-pilot for onboarding and help. More details — Assistant.
| Метод и путь | Описание |
|---|---|
GET /assistant/threads | List of threads |
GET /assistant/threads/{id}/messages | Thread message history |
DELETE /assistant/threads/{id} | Delete a thread |
POST /assistant/chat | Send a message to the assistant |
Real-time message stream
Section titled “Real-time message stream”There are two independent live update channels. More details — on the WebSocket page.
WebSocket (/ws)
Section titled “WebSocket (/ws)”The main channel for delivering real-time push messages. Connect using a client token in the token query parameter:
# Using wscatwscat -c "wss://host/ws?token=CaQw5lL_L.yiRbN"const ws = new WebSocket("wss://host/ws?token=CaQw5lL_L.yiRbN");ws.onmessage = (event) => { const msg = JSON.parse(event.data); console.log(`[${msg.title}] ${msg.message} (приоритет: ${msg.priority})`);};Each incoming event is a JSON object Message:
{ "id": 124, "appid": 1, "message": "Новое сообщение", "title": "Заголовок", "priority": 5, "extras": {}, "date": "2025-06-01T10:31:00Z"}SSE (/stream)
Section titled “SSE (/stream)”A separate endpoint for Server-Sent Events (GET /stream, Content-Type: text/event-stream) for live UI updates. It’s a regular HTTP GET stream—use EventSource in the browser (authentication via cookie session or client token). The server sends named events (for example connected, channel:status_changed) and periodic keepalive comments.
const es = new EventSource("https://host/stream", { withCredentials: true });es.addEventListener("connected", () => console.log("подключено"));es.onmessage = (event) => console.log(event.data);Examples in different languages
Section titled “Examples in different languages”Python
Section titled “Python”import requests
# Send a messagerequests.post("https://host/message?token=AGdjfk_L.dKe8q", json={ "title": "Бэкап", "message": "Резервное копирование завершено", "priority": 2,})
# Get all messagesresp = requests.get("https://host/message", auth=("admin", "admin"))for msg in resp.json()["messages"]: print(f"[{msg['title']}] {msg['message']}")package main
import ( "net/http" "net/url")
func main() { http.PostForm("https://host/message?token=AGdjfk_L.dKe8q", url.Values{ "title": {"Deploy"}, "message": {"Версия 2.0 развёрнута"}, })}JavaScript (Node.js)
Section titled “JavaScript (Node.js)”// Send messageconst resp = await fetch("https://host/message?token=AGdjfk_L.dKe8q", { method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify({ title: "CI", message: "Тесты пройдены", priority: 3, }),});console.log(await resp.json());PowerShell
Section titled “PowerShell”# Send messageInvoke-RestMethod -Uri "https://host/message?token=AGdjfk_L.dKe8q" ` -Method POST -Body @{ title = "Отчёт" message = "Ежедневный отчёт сгенерирован" priority = 1 }Status codes
Section titled “Status codes”| Код | Значение |
|---|---|
200 | Success |
400 | Bad request (invalid parameters) |
401 | Unauthorized (missing or invalid token) |
403 | Forbidden (insufficient permissions) |
404 | Resource not found |