Quotas, plans and pricing
Notifly operates on a model of daily quotas. The main unit of accounting is an event:
any action that generates a notification or consumes platform resources
charges exactly one event. When the daily limit is exhausted, new events on the
same day are rejected — until the counter resets at 00:00 Moscow time.
For example, POST /message then responds with 429 Too Many Requests.
Every feature is available on every plan — plans differ only in their limits. Current prices and values:
| Limit | Free | Pro | Business |
|---|---|---|---|
| Price per month | 0 ₽ | 299 ₽ | 999 ₽ |
Events/day (dailyEvents) | 1 000 | 100 000 | Unlimited |
AI requests/day (aiRequestsPerDay) | 50 | 2 000 | 50 000 |
Assistant requests/day (assistantRequestsPerDay) | 100 | 5 000 | 100 000 |
Port scans/day (portScansPerDay) | 10 | 300 | 10 000 |
Devices (devices) | 3 | 15 | Unlimited |
Status pages (statusPages) | 1 | 5 | Unlimited |
Screenshot storage (storageMB) | 50 MB | 1 GB | 10 GB |
- Devices — the number of simultaneously active clients (applications receiving notifications). When downgrading the plan, excess devices are automatically moved to suspended (the oldest active clients are disabled).
- Unlimited is not “infinity” but an unreachable ceiling: a limit of 1,000,000,000 or more is treated as unlimited, and the admin UI shows “Unlimited” instead of a progress bar.
- Status pages — the number of public status pages per account. Hiding the “powered by Notifly” badge starts with Pro.
- Storage is not a daily quota but a persistent volume: see Screenshot storage below.
Estimating your usage
Section titled “Estimating your usage”An event is not just a message: every monitor check and every heartbeat ping also costs one event, even when everything is fine and no notification is sent. That is why monitors are usually the main consumer of the quota, and it is best to count from their interval:
| What is running | Events per day |
|---|---|
| A monitor checking every 5 minutes | 288 |
| A monitor checking every minute | 1 440 |
| A monitor checking every 30 seconds (minimum for HTTP and protocol monitors) | 2 880 |
| A heartbeat from an hourly cron job | 24 |
| A script sending 50 messages a day | 50 |
An example for Free (1,000 events a day): three monitors every 5 minutes (3 × 288 = 864) plus one hourly heartbeat (24) come to 888 events, leaving about a hundred for messages. But a single monitor checking every minute (1,440) already does not fit into Free — for that interval you need Pro, or check less often.
Minimum check intervals: protocol and HTTP monitors — 30 seconds; content, port and API workflow monitors — 60 seconds; browser workflows — 5 minutes. The actual usage for the day per monitor and source is shown in the quota breakdown.
What happens when the quota runs out:
- sending messages (
POST /message) and heartbeat pings are rejected with429 Too Many Requests; - monitors are not switched off — they postpone their checks until the counter reset (00:00 Moscow time, with a margin of a few minutes) and then carry on by themselves;
- once a day a “Daily quota exhausted” notification arrives in the System service channel, with a breakdown of what the events were spent on.
One action — one deduction
Section titled “One action — one deduction”A deduction happens at the moment of the action — a check, a ping, sending a point, receiving an email — not for the resulting notification. From this follows:
- a monitor check that triggered an alert charges only the check event
(
monitor/http_monitor/content_monitor/port_monitor/workflow_monitor) — there is no separate event for alert or recovery; - a heartbeat recovery notification does not charge anything beyond the already counted
heartbeat; - exception —
heartbeat_alert: the “missed ping” alert has no ping of its own (the ping didn’t arrive), so it is counted as a separate event; - metric alerts are counted via the
metricpoint; there is no separate event for an alert; - email and webhook router are counted on arrival: one incoming email =
one
emailevent, one incoming router payload = onerouterevent, regardless of how many channels they are forwarded to (forwarding to channels is not charged separately); - a single action is never charged twice under different categories.
When the limit is exceeded the user receives a system notification once per day that the quota is exhausted.
Event types
Section titled “Event types”Each deduction belongs to one of the event types. These same keys appear in quota breakdown and in the admin.
| Key | When charged | Limit |
|---|---|---|
message | Each incoming message to a channel | dailyEvents |
heartbeat | Each ping of the heartbeat | dailyEvents |
heartbeat_alert | Triggering of the “missed ping” alert | dailyEvents |
monitor | Each check of a protocol monitor (TCP/DNS/TLS, etc.) | dailyEvents |
http_monitor | Each check of an HTTP monitor | dailyEvents |
content_monitor | Each check of a content monitor | dailyEvents |
port_monitor | Each check of a port monitor | dailyEvents |
workflow_monitor | Each check of a multi-step API workflow monitor | dailyEvents |
port_scan | Each discovery port scan of a host | portScansPerDay |
web_script | Each trigger of the web script | dailyEvents |
metric | Each sent metric point | dailyEvents |
ask | Each question posed to the ask monitor | dailyEvents |
email | Arrival of an email in the inbox (once per email) | dailyEvents |
router | Incoming payload to the webhook router (once per request) | dailyEvents |
ai_request | Call to AI/LLM (choosing a router rule, selector, or workflow step) | aiRequestsPerDay |
assistant_request | Dialog interaction with the chat assistant | assistantRequestsPerDay |
Screenshot storage
Section titled “Screenshot storage”Screenshots taken by browser workflows and browser
content monitors occupy object storage and are counted
against a separate, non-daily storageMB quota.
- Only frames referenced by an alert message count; frames from failed runs without an alert are deleted right away and take no space.
- When the used volume exceeds the plan limit, the oldest screenshots are evicted FIFO — new frames are always kept.
- On a plan downgrade the storage is not trimmed instantly: the nightly cleanup and the eviction on the next screenshot upload bring it down to the new limit.
The current value is in the GET /user/quota-breakdown response (the storage
field: usedBytes and limitBytes).
Counter reset
Section titled “Counter reset”All daily counters are reset on schedule at 00:00 MSK. The historical breakdown by day is not removed — the new day simply starts counting from zero, and past days’ statistics remain available.
Rate limit for the scripts ingest endpoint
Section titled “Rate limit for the scripts ingest endpoint”In addition to the daily quota, the public ingest endpoint for the web script
(POST /script/:token) is protected by a separate rate limit: no more than
120 requests per minute per token (fixed window). When exceeded the server responds with
HTTP 429 Too Many Requests with a Retry-After header
(seconds until the end of the current window) and a body:
{"ok": false, "error": "rate limited"}The client SDK batches events itself and enforces a hard limit of 100 POSTs per session, so 120/min comfortably covers legitimate traffic. The limit is applied per-token and is counted separately from the daily events quota.
Pricing and how to pay
Section titled “Pricing and how to pay”Free costs nothing, Pro is 299 ₽ per month and Business is 999 ₽ per month. There is no card payment yet — Pro and Business are paid by bank transfer against an invoice. Here is how it works:
- Email support@notifly.ru with the plan you need (Pro — 299 ₽ per month, or Business — 999 ₽ per month), the period, and the e-mail of the Notifly account it should be enabled for.
- Receive an invoice with the payment details — it is sent in reply to your email.
- Pay the invoice by bank transfer. In the payment reference, put the invoice number and your account e-mail — this makes it quicker to match the payment to your account.
- Wait for the operator’s reply. Once the payment arrives, an operator switches your account to the new plan and lets you know. The new limits apply immediately; monitors that were on hold because the quota ran out resume their checks right away, without waiting for the counter reset.
Your current plan and today’s usage are shown in the admin under Profile, and the prices of all plans — on the Pricing page (the Upgrade plan menu item). The Subscribe button on the plan cards does nothing yet — use email.
Downgrading is self-service and takes effect immediately. Excess devices are automatically moved to suspended — the oldest active clients are disabled until the new limit is met; screenshot storage is brought within the new limit by the nightly cleanup.
For developers
Section titled “For developers”- You cannot upgrade a plan yourself from the admin or via the API: for a
regular user
POST /current/user/planaccepts only a downgrade (or the current plan), and an upgrade request gets402 Payment Required. Upgrades are performed by an operator after payment. - The balance is shown in your profile. For a regular user the Top up
button does not credit money yet: the server replies
402suggesting payment by bank transfer ("paymentMethod": "bank_transfer"). Direct top-up (POST /current/user/topup) is available to administrators only.
Quota breakdown
Section titled “Quota breakdown”GET /user/quota-breakdown returns detailed usage statistics for the current
user for a day (by default — today in MSK; another day — via
?day=YYYY-MM-DD):
curl -H "X-Notifly-Key: C_xxx" \ "$NOTIFLY_URL/user/quota-breakdown?day=2026-06-23"The response contains:
day— the date (YYYY-MM-DDin MSK);rows— row-wise breakdown “event type × resource” with a human-readable resource name;hourly— hourly events consumption for the day;series— per-minute consumption split into three series:events(main quota),ai(AI requests) andportscan(port scans);storage— a snapshot of the used storage at request time:usedBytesagainstlimitBytes(not a daily quota, see Screenshot storage).
REST API
Section titled “REST API”Base URL — https://api.notifly.ru (or $NOTIFLY_URL). Authorization header —
X-Notifly-Key (client-token, prefix C).
| Method | Path | Purpose |
|---|---|---|
GET | /user/quota-breakdown | Detailed daily usage breakdown (?day=YYYY-MM-DD optional) |
POST | /current/user/topup | Top up balance. Body: {"amountRubles": N} (integer ≥ 1). Direct top-up — only for administrators; regular users receive 402 ("paymentMethod": "bank_transfer") |
POST | /current/user/plan | Change plan. Body: {"plan": "free"|"pro"|"business"}. Regular users can only downgrade; an upgrade returns 402. When downgrading it suspends excess devices (response includes suspendedDevices) |