Forward or route alert emails from any monitoring tool, ticketing system, or mailbox to a dedicated inbound address, and turn them into incidents automatically.
The Email alert source turns emails you forward or route to a dedicated inbound address into incidents. Use it for any monitoring or alerting tool that can only notify by email (no webhook option), or for anywhere alerts already land in an inbox: a shared ops mailbox, a legacy paging system, a vendor that only offers email notifications.
Unlike the webhook presets on this section's other pages, an Email source has no JSON payload. It parses the email's subject and plain-text body with its own selector language (below), not the dot/bracket Selector paths those guides use.
1. Create the alert source in Uptimeify
Go to Incident Management → Alert Sources → New and pick the Email option (alongside the webhook presets), name it, and create it. On the success screen, copy the inbound address. It has the shape <token>@ingest.uptimeify.io and is shown once, never displayed again in cleartext. If you lose it, rotate the token from the source's Settings tab to get a fresh address.
2. Point your alerts at the address
There is no fixed sender or vendor. Anything that can deliver a plain-text email works:
- Set the address as the notification/contact target in a monitoring tool that only supports email alerting.
- Add a forwarding rule in your mailbox (Gmail, Outlook, a shared ops alias, …) that forwards matching alert emails to it.
- Point an existing mail-routing rule or relay at it, if alerts already flow through one.
Only the plain-text body is read. An HTML-only email with no plain-text part resolves to an empty body for selector purposes. The subject is still available.
Default field mapping (zero configuration)
A freshly created Email source works with no further setup, using these defaults:
| Field | Default source | Notes |
|---|---|---|
| Title | Subject header, verbatim | |
| Status | open, unless the subject contains the whole word resolved, recovered, or cleared (case-insensitive) | Only the subject is scanned for these, never the body, so a firing alert's body prose (e.g. "checks are not ok") can never be mistaken for a resolution |
| Severity | The source's configured default severity | Every email uses it until you add a severity selector + severityMap |
| Host | Empty | Until you add a host selector |
| Dedup key | A deterministic hash of the title + sender address | Until you add a dedupKey selector |
The email selector language
Email selectors are a small, separate syntax from the JSON Selector paths used by webhook sources. An email has no JSON structure to walk:
| Selector | Resolves to |
|---|---|
subject | The email's Subject header, verbatim |
body | The plain-text body, verbatim |
body.line(N) | The Nth line of the plain-text body, 1-indexed (body.line(1) is the first line) |
subject =~ /pattern/ | Regex match against the subject: the first capturing group (...) if the pattern has one, otherwise the whole match |
body =~ /pattern/ | Same, matched against the plain-text body |
A selector may chain fallbacks with ||, same convention as the webhook Selector paths: the first candidate that resolves to a non-empty value wins:
subject =~ /Status: (\w+)/ || body.line(1)A missing field, an out-of-range line, or an invalid/non-matching regex all resolve to nothing rather than erroring. A malformed or unexpected email is normal, reachable input, not a bug.
Customizing the mapping
There is currently no dedicated mapping editor in the dashboard for Email sources (the Payload Mapping tab's selector editor targets the JSON webhook shape). To configure selectors, use the API:
GET /api/im/sources/:idto read the source's currentpayloadMapping. You need the FULL object back, not just the part you're changing (see the warning below).PATCH /api/im/sources/:idwith the completepayloadMapping, adding or editing anemailSelectorskey inside it:
curl -X PATCH "https://<your-domain>/api/im/sources/<id>" \
-H "Content-Type: application/json" \
-H "Cookie: <your-session-cookie>" \
-d '{
"payloadMapping": {
"title": "title",
"severity": "severity",
"severityMap": { "sev1": "sev1", "sev2": "sev2", "sev3": "sev3", "sev4": "sev4" },
"status": "status",
"resolveValues": ["resolved"],
"host": "host",
"dedupKey": "dedupKey",
"emailSelectors": {
"title": "subject",
"severity": "subject =~ /\\[(CRITICAL|WARNING)\\]/",
"severityMap": { "CRITICAL": "sev1", "WARNING": "sev3" },
"resolveValues": ["resolved", "recovered", "cleared"]
}
}
}'A PATCH replaces the entire payloadMapping value, it does not merge. Sending only { "payloadMapping": { "emailSelectors": {...} } } drops the other fields (title, severity, status, host, dedupKey, resolveValues) that Uptimeify's ingest pipeline needs internally, breaking the source. Always send the full object back, starting from a fresh GET.
The emailSelectors sub-object accepts:
| Key | Type | Purpose |
|---|---|---|
title | selector | Defaults to subject |
severity | selector | Raw value looked up in severityMap |
severityMap | object | Maps a raw extracted value to sev1 to sev4 |
status | selector | If set, its resolved value is checked against resolveValues; if unset, the zero-config subject scan (above) applies instead |
resolveValues | array of strings | Case-insensitive tokens that mean "resolved". Defaults to ["resolved", "recovered", "cleared"] |
host | selector | |
dedupKey | selector | Defaults to a hash of title + sender address |
custom | object of selectors | Extra fields, surfaced the same way a webhook source's custom mapping is |
Response
Every inbound email that reaches a valid address is accepted for asynchronous processing. There is no synchronous success/failure signal the way a webhook's 202 Accepted provides, since mail delivery itself is the transport. An email whose selectors resolve to no title is dropped (nothing to page on) rather than creating an empty incident.