Skip to content

Email Inbox (receiving emails as notifications)

Email Inbox is a “mailbox” that uses Notifly channels instead of your IMAP. When you create an inbox, you get a unique email address like <alias>@in.notifly.ru. Everything sent to it is processed by routing rules: each rule checks a filter to decide which channel to send a notification to and with what title/text.

This is convenient when an external system only knows how to send email and teaching it to use HTTP is too expensive:

  • alerts from hosting providers, billing systems, RBLs and registrars;
  • notifications from CI/CD, backup systems, third-party SaaS;
  • transactional email from your own backend (orders, registrations) without a separate push channel;
  • alerts from legacy hardware monitoring systems that only support SMTP.

The inbox itself is not bound to a channel — it only accepts mail. Routing is performed by separate rules. So setup consists of two steps:

  1. Create an inbox → get the address <alias>@in.notifly.ru and put it into the external service settings.
  2. Add a rule (or several) → specify a filter (when the rule should trigger) and the recipient channel.

If the inbox has no rules, an incoming email produces no notifications (with history enabled it lands there with status unmatched). Emails are checked against the enabled rules in ascending position; for each matching rule a notification is created in its channel.

SMTP sender ──► <alias>@in.notifly.ru
│
▼
Notifly incoming mail handler
│ 1. extract alias from the address
│ 2. find the inbox by alias
│ 3. run the email through the inbox rules (by position)
│ 4. for each matching rule — title/message by template
▼
message in the rule's channel + push (for each matching rule)
│
▼
All your clients receive the notifications
  • Routing — by the alias in the local part of the address.
  • The notification is an ordinary channel message: WebSocket push, the GET /message feed, escalation, quiet hours and the channel’s maintenance windows work as for any message.
  • Every incoming email is one event of the daily quota, however many rules match. When the quota is exhausted the email is dropped (it does not reach the history) and you get a quota notification.
  • Optionally incoming emails are saved in the history (see saveEvents below).
  1. Open app.notifly.ru → Integrations → Email inboxes.
  2. Click “Create email inbox”, fill in:
    • Inbox name — display name, e.g. “Reg.ru Alerts”.
    • Save incoming emails to history — whether to store email texts in history (saveEvents).
  3. The generated email address will appear on the card — this is the authentication. Copy it to the external service settings.

Request body — EmailInboxParams: {name, saveEvents}. The inbox does not have an appId — the channel is assigned by rules.

Окно терминала
curl -X POST "$NOTIFLY_URL/email-inbox" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{
"name": "Reg.ru Alerts",
"saveEvents": true
}'

The response will contain the inbox object with emailAddress filled:

{
"id": 17,
"name": "Reg.ru Alerts",
"alias": "a3f9c21b8e04",
"emailAddress": "a3f9c21b8e04@in.notifly.ru",
"saveEvents": true,
"created": "2026-04-30T10:11:12Z",
"lastUsed": null
}

alias is 12 hex characters, generated automatically and immutable.

A rule (EmailInboxRule) describes which emails to catch and where to send them. A rule has:

FieldPurpose
appIdrecipient channel (required; only your own channel)
namerule name for display
filtertrigger conditions (see below); empty filter = “always matches”
titleTemplatenotification title template; empty → email subject
messageTemplatenotification message template; empty → email body
prioritynotification priority; 0 (default) — the channel’s priority
enabledwhether the rule is enabled (defaults to true)
positionevaluation order (ascending)

In titleTemplate / messageTemplate templates the following placeholders are available: {subject}, {body}, {from}, {to}, {date}, {alias} (single curly braces; {date} is the moment the email was received, UTC, RFC3339).

The admin UI does not set a rule priority — notifications arrive with the channel’s default priority. The “From template…” button in the rule dialog pre-fills the form with ready recipes: “Cron alerts” (subject contains FAIL or ERROR), “Online store orders” and “Ignore newsletters” (only emails without a List-Unsubscribe header get through).

filter (EmailFilter) is a match plus a list of conditions:

  • match: "all" — all conditions must be met (AND, default);
  • match: "any" — at least one condition must be met (OR);
  • empty conditions means “always matches” (default rule).

Each condition (EmailFilterCondition) has field, op, value (and caseSensitive, default false).

Fields (field):

fieldWhat it checks
fromFrom header (address or name)
toTo header (address)
subjectemail subject
bodyemail plain-text body
headerarbitrary header (name in headerName, the name is case-insensitive; a missing header is an empty string)

Operators (op):

opMeaning
containssubstring
not_containsabsence of substring
equalsexact match
not_equalsexact mismatch
starts_withprefix
ends_withsuffix
matchesRE2 regular expression

Unless caseSensitive: true is set, comparison (and regex) is case-insensitive.

Окно терминала
curl -X POST "$NOTIFLY_URL/email-inbox/17/rules" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{
"appId": 12345,
"name": "Critical backup alerts",
"filter": {
"match": "all",
"conditions": [
{"field": "from", "op": "contains", "value": "@reg.ru"},
{"field": "subject", "op": "starts_with", "value": "[ALERT]"}
]
},
"titleTemplate": "Reg.ru: {subject}",
"messageTemplate": "{body}",
"priority": 8,
"position": 0
}'

The response is the full rule object with id, filled appName and default values (enabled: true).

{
"field": "header",
"headerName": "X-Priority",
"op": "equals",
"value": "1"
}

Step 2 (quick). Rule from an example email (AI)

Section titled “Step 2 (quick). Rule from an example email (AI)”

If you already enabled saveEvents, you don’t need to craft the filter manually: send a test email, find it in the history and ask Notifly to suggest a rule based on that example — POST /email-inbox/rule/from-event/:eid.

Окно терминала
# Without prompt — heuristic: sender domain + a keyword from the subject (no LLM).
curl -X POST "$NOTIFLY_URL/email-inbox/rule/from-event/981" \
-H "X-Notifly-Key: <api-token>"
# With prompt — pick filter and templates using AI (1 request from the AI-helper quota).
curl -X POST "$NOTIFLY_URL/email-inbox/rule/from-event/981" \
-H "Content-Type: application/json" \
-H "X-Notifly-Key: <api-token>" \
-d '{"prompt": "catch only emails about replication failure, title — concise"}'

The response is a draft {filter, titleTemplate, messageTemplate}: you need to add appId and send it to POST /email-inbox/:id/rules.

If an inbox has saveEvents: true, every incoming email is saved as an EmailInboxEvent: from, to, subject, bodyRaw, headers (headers — lower-case names, first value), and also status (matched / unmatched), matchedRuleIds and createdMessageIds. This is useful for audit (“why didn’t the email arrive?”) and for generating rules from an example. Events are kept for 30 days.

Окно терминала
# List emails; filters: q (subject, sender, text), status, inbox_id,
# from, to (RFC3339), limit (default 50, max 100), cursor (id of the last event).
curl "$NOTIFLY_URL/email-inbox/event?inbox_id=17&status=unmatched&limit=50" \
-H "X-Notifly-Key: <api-token>"
# Single email in full.
curl "$NOTIFLY_URL/email-inbox/event/981" -H "X-Notifly-Key: <api-token>"
# Delete an entry from history.
curl -X DELETE "$NOTIFLY_URL/email-inbox/event/981" -H "X-Notifly-Key: <api-token>"

Any SMTP client sends an email to the provided address — no authorization headers are needed (alias itself is the secret):

Окно терминала
# msmtp / mailx
echo "The database was not refreshed overnight — check replication." \
| mail -s "[ALERT] backups: lag > 24h" \
"a3f9c21b8e04@in.notifly.ru"

From Python:

import smtplib
from email.message import EmailMessage
msg = EmailMessage()
msg["To"] = "a3f9c21b8e04@in.notifly.ru"
msg["From"] = "alerts@example.com"
msg["Subject"] = "[ALERT] backups: lag > 24h"
msg.set_content("The database was not refreshed overnight — check replication.")
with smtplib.SMTP("smtp.example.com", 587) as s:
s.starttls()
s.login("user", "pass")
s.send_message(msg)
Notification fieldWhere it comes from
titlerule’s titleTemplate; if empty — email subject (Subject:), without a subject — (no subject)
messagerule’s messageTemplate; if empty — email plain-text body
priorityrule’s priority; 0 — the channel’s default priority
channelrule’s appId

The notification text is marked as Markdown (client::display). Attachments are not saved.

Method & pathAuthorizationPurpose
GET /email-inboxAPI tokenlist inboxes (with rules)
POST /email-inboxAPI token (write)create an inbox {name, saveEvents}
PUT /email-inbox/:idAPI token (write)update {name, saveEvents}
DELETE /email-inbox/:idAPI token (write)delete an inbox
GET /email-inbox/:id/rulesAPI tokenlist inbox rules
POST /email-inbox/:id/rulesAPI token (write)create a rule
PUT /email-inbox/:id/rules/:ridAPI token (write)update a rule
DELETE /email-inbox/:id/rules/:ridAPI token (write)delete a rule
GET /email-inbox/eventAPI tokenincoming history (with filters)
GET /email-inbox/event/:eidAPI tokensingle email
DELETE /email-inbox/event/:eidAPI tokendelete history entry
POST /email-inbox/rule/from-event/:eidAPI tokensuggest a rule from an example (AI)

An API token (M…) is required; changes need one with write access. Channel tokens (including shared ones) are not accepted here — 403.

POST /email-inbox always returns the full EmailInbox object, including the public emailAddress (convenient to copy immediately to the external system settings). POST/PUT rules return the full EmailInboxRule object with appName.

  • The notification gets the email’s plain-text body; attachments are not saved.
  • A body longer than 1 MB is truncated — both in the notification and in the history (bodyTruncated: true).
  • Every email is one event of the daily quota; emails over the quota are dropped.
  • Without rules emails produce no notifications — add at least one rule with an empty filter to catch everything.
  • AI-based rule generation with prompt charges one request from the daily AI-helper quota.