---
title: "Email"
description: "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:

1. `GET /api/im/sources/:id` to read the source's current `payloadMapping`. You need the FULL object back, not just the part you're changing (see the warning below).
2. `PATCH /api/im/sources/:id` with the complete `payloadMapping`, adding or editing an `emailSelectors` key inside it:

```bash
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"]
      }
    }
  }'
```

<Callout type="warn">
  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`.
</Callout>

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.
