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.
Two setup steps
Section titled “Two setup steps”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:
- Create an inbox → get the address
<alias>@in.notifly.ruand put it into the external service settings. - 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.
How it works
Section titled “How it works”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
aliasin the local part of the address. - The notification is an ordinary channel message: WebSocket push, the
GET /messagefeed, 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
saveEventsbelow).
Step 1. Creating an inbox
Section titled “Step 1. Creating an inbox”Via the admin UI
Section titled “Via the admin UI”- Open app.notifly.ru → Integrations → Email inboxes.
- 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).
- The generated email address will appear on the card — this is the authentication. Copy it to the external service settings.
Via the REST API
Section titled “Via the REST API”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.
Step 2. Routing rules
Section titled “Step 2. Routing rules”A rule (EmailInboxRule) describes which emails to catch and
where to send them. A rule has:
| Field | Purpose |
|---|---|
appId | recipient channel (required; only your own channel) |
name | rule name for display |
filter | trigger conditions (see below); empty filter = “always matches” |
titleTemplate | notification title template; empty → email subject |
messageTemplate | notification message template; empty → email body |
priority | notification priority; 0 (default) — the channel’s priority |
enabled | whether the rule is enabled (defaults to true) |
position | evaluation 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
Section titled “Filter”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
conditionsmeans “always matches” (default rule).
Each condition (EmailFilterCondition) has field, op,
value (and caseSensitive, default false).
Fields (field):
field | What it checks |
|---|---|
from | From header (address or name) |
to | To header (address) |
subject | email subject |
body | email plain-text body |
header | arbitrary header (name in headerName, the name is case-insensitive; a missing header is an empty string) |
Operators (op):
op | Meaning |
|---|---|
contains | substring |
not_contains | absence of substring |
equals | exact match |
not_equals | exact mismatch |
starts_with | prefix |
ends_with | suffix |
matches | RE2 regular expression |
Unless caseSensitive: true is set, comparison (and regex) is case-insensitive.
Creating a rule
Section titled “Creating a rule”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).
Header example (header)
Section titled “Header example (header)”{ "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.
Incoming history (saveEvents)
Section titled “Incoming history (saveEvents)”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>"Sending an email
Section titled “Sending an email”Any SMTP client sends an email to the provided address — no authorization headers are needed (alias itself is the secret):
# msmtp / mailxecho "The database was not refreshed overnight — check replication." \ | mail -s "[ALERT] backups: lag > 24h" \ "a3f9c21b8e04@in.notifly.ru"From Python:
import smtplibfrom 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)What will be in the notification
Section titled “What will be in the notification”| Notification field | Where it comes from |
|---|---|
title | rule’s titleTemplate; if empty — email subject (Subject:), without a subject — (no subject) |
message | rule’s messageTemplate; if empty — email plain-text body |
priority | rule’s priority; 0 — the channel’s default priority |
| channel | rule’s appId |
The notification text is marked as Markdown (client::display). Attachments
are not saved.
REST API
Section titled “REST API”| Method & path | Authorization | Purpose |
|---|---|---|
GET /email-inbox | API token | list inboxes (with rules) |
POST /email-inbox | API token (write) | create an inbox {name, saveEvents} |
PUT /email-inbox/:id | API token (write) | update {name, saveEvents} |
DELETE /email-inbox/:id | API token (write) | delete an inbox |
GET /email-inbox/:id/rules | API token | list inbox rules |
POST /email-inbox/:id/rules | API token (write) | create a rule |
PUT /email-inbox/:id/rules/:rid | API token (write) | update a rule |
DELETE /email-inbox/:id/rules/:rid | API token (write) | delete a rule |
GET /email-inbox/event | API token | incoming history (with filters) |
GET /email-inbox/event/:eid | API token | single email |
DELETE /email-inbox/event/:eid | API token | delete history entry |
POST /email-inbox/rule/from-event/:eid | API token | suggest 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.
Limitations
Section titled “Limitations”- 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
promptcharges one request from the daily AI-helper quota.