---
title: Email round-trip monitoring: delivery time, inbox vs spam, SPF/DKIM/DMARC
description: Send a test message through your SMTP server, find it in a mailbox over IMAP or POP3 and measure the delivery time, inbox or spam folder, SPF/DKIM/DMARC results, spam score and every relay hop — then delete it.
canonical: https://watchfor.io/docs/monitors/email-round-trip
---

# Email round-trip monitoring: delivery time, inbox vs spam, SPF/DKIM/DMARC

Send a test message through your SMTP server, find it in a mailbox over IMAP or POP3 and measure the delivery time, inbox or spam folder, SPF/DKIM/DMARC results, spam score and every relay hop — then delete it.

Every part of your mail setup can look healthy on its own and mail still
doesn't arrive: the SMTP server answers, the DNS records are published, the
IP is on no blocklist, and yet password resets sit in a queue for twenty
minutes or land in spam. The only way to know that mail gets through is to
send some. An **email round-trip monitor** does that on a schedule.

Each check:

1. logs in to the receiving mailbox over IMAP or POP3 (no message is sent
   unless it can be found and deleted afterwards);
2. connects to your SMTP server, negotiates TLS, logs in and sends one
   short, fixed test message;
3. checks the mailbox every 2 seconds until the message arrives or the
   delivery timeout runs out, looking in the Inbox and, over IMAP, the spam
   folder;
4. reads the delivered message's headers: which folder it landed in, the
   SPF, DKIM and DMARC results, the spam score, antivirus marks and every
   relay hop with its delay and encryption;
5. deletes the test message, plus any probe message left over from an
   earlier check that is older than an hour.

**Target:** the host name of the server you send mail through (SMTP
submission), for example `smtp.example.com` or `smtp.gmail.com`.

Email round-trip monitors are on the **Pro** and **Business** plans. Because
every check sends a real message, the shortest interval is **5 minutes**
(10 minutes when you create one).

## The test message

The content is fixed: the subject is `WatchFor delivery check <token>`, the
body is a short fixed text, and an `X-WatchFor-Probe: <token>` header
carries a random token that identifies this one check. Only the addresses
and the token vary, so a round-trip monitor can't be used to send arbitrary
mail. The monitor finds its message by that header, never by reading other
mail in the mailbox.

Use a **dedicated test mailbox** where you can. The check needs to log in to
it and deletes its own messages, and a mailbox nobody reads keeps the
results free of filters and rules a person has set up.

## Settings

**Send (SMTP)**

| Setting | Notes |
| --- | --- |
| **Encryption** | **STARTTLS** (port 587, the default) or **Implicit TLS** (port 465). Port 25 is never used for sending: it is meant for server-to-server mail, and cloud networks block it outbound. |
| **Port** | Follows the encryption mode unless you type a custom port (any port except 25). |
| **Username** and **Password** | Required. The login your apps or mail client use to send. The password is stored encrypted and never shown again. |
| **Verify certificate** | On by default: fail when the certificate is expired, self-signed or for another name. |

**Receive (IMAP / POP3)**

| Setting | Notes |
| --- | --- |
| **Protocol** | **IMAP** (default) or **POP3**. Only IMAP can look in the spam folder. |
| **Server** | The receiving mailbox's IMAP or POP3 host, for example `imap.example.com`. |
| **Encryption** and **Port** | **Implicit TLS** (993 IMAP / 995 POP3, the default) or **STARTTLS** (143 / 110). |
| **Same login as sending** | Off by default. On logs in to the mailbox with the sending username and password, for the common case of sending to yourself. |
| **Username** and **Password** | The mailbox login, when it differs from the sending one. Stored encrypted. |
| **Verify certificate** | On by default. |

**Message and timing**

| Setting | Notes |
| --- | --- |
| **Send to** | Required. The address of the mailbox you receive in, often the address you send from. When the mailbox login is an email address, this must be at the same domain (aliases are fine). |
| **Send from** | Optional; defaults to the sending username. When that username is an email address, the From must be it or at its domain. Your SMTP server decides which From addresses the login may use. |
| **Mailbox** | IMAP folder to look in, `INBOX` by default. |
| **Delivery timeout** | How long to wait for the message: 10 to 240 seconds, 120 when left empty. A message that arrives later counts as not delivered. |
| **Look in the spam folder too** | IMAP only, on by default. When the message is not in the Inbox, check the spam folder: a mailbox marked `\Junk`, otherwise a folder named Junk, Spam, Junk E-mail, Junk Email or Bulk Mail. A message found there counts as delivered to spam, not lost. |
| **Delete the test message** | On by default. Off leaves each message in the mailbox so you can inspect it; leftovers are still deleted after an hour. |
| **Timeout** | Seconds per connection (default 15). |

Gmail needs an [app password](https://support.google.com/accounts/answer/185833)
for both sending and receiving. Microsoft 365 and Outlook.com have turned off
password logins for IMAP and POP3 and are retiring them for SMTP; WatchFor
doesn't support OAuth sign-in yet, so a Microsoft 365 mailbox can't be the
receiving side today.

## What each check reports

| Result | What it tells you |
| --- | --- |
| **Delivered** | Whether the message arrived within the delivery timeout. |
| **Delivery time** | From the moment your SMTP server accepted the message to the moment the monitor found it in the mailbox (checked every 2 seconds over IMAP; over POP3 every 2 seconds for the first 30, then every 5, because each POP3 look is a full login). |
| **Inbox or spam** | Which folder it landed in (IMAP with the spam folder check on). |
| **SPF, DKIM, DMARC** | The receiving server's verdicts from its `Authentication-Results` header (or `ARC-Authentication-Results`). Only the receiving server's own header is trusted; results added further upstream are ignored. |
| **Spam score** | The receiving filter's score and verdict when it left one: SpamAssassin (`X-Spam-Status`, `X-Spam-Score`, `X-Spam-Flag`), rspamd (`X-Rspamd-Score`, `X-Spam`) or Microsoft 365 (`X-MS-Exchange-Organization-SCL`, `X-Forefront-Antispam-Report`). |
| **Antivirus** | Whether a virus scanner marked the message (`X-Virus-Scanned`, `X-Virus-Status`, amavis headers). |
| **Hops** | Every relay from the `Received` headers in delivery order, with the delay at each hop and whether it was encrypted. Hand-offs inside one system (local or LMTP delivery, loopback or private addresses) don't count against the encryption check. |
| **Stages** | Connect, TLS and login times on both sides, the send time, and the stage where a failed check stopped. |

SPF, DKIM, DMARC, the spam score and the antivirus mark come from headers
the receiving server writes. When it writes none, those values are simply
missing from the check, and rules on them don't fire.

## Alert presets

| Preset | Default | Fires when |
| --- | --- | --- |
| **Probe Status** | on (locked, critical) | The SMTP connection, login or submission fails, the mailbox login fails, or the message does not arrive in time. |
| **Message Not Delivered** | on (critical) | The message was sent but never showed up in the Inbox or the spam folder within the delivery timeout. |
| **Landed in Spam** | on (warning) | The message arrived in the spam folder instead of the Inbox. |
| **Slow Delivery** | off | Delivery took longer than 60000 ms (a minute). |
| **SPF Failed** | off | The receiving server says SPF did not pass for the sending server. |
| **DKIM Failed** | off | The receiving server could not verify the message's DKIM signature, or there was none. |
| **DMARC Failed** | off | The DMARC verdict for the From domain is not a pass. |
| **Unencrypted Relay Hop** | off | A `Received` header shows a relay hop without TLS. |

Every preset except Probe Status opens an incident after **two** failing
checks in a row (each check sends a real message, five or more minutes
apart), and two good checks close an incident.

### Metrics for custom rules

All round-trip metrics are in the `roundtrip.` namespace, for example
`metrics['roundtrip.spam_score'] > 5`.

| Metric | Meaning |
| --- | --- |
| `roundtrip.delivered` | `1` arrived within the timeout, `0` not. |
| `roundtrip.delivery_ms` | Delivery time in milliseconds. |
| `roundtrip.in_spam` | `1` found in the spam folder. |
| `roundtrip.spf_pass`, `roundtrip.dkim_pass`, `roundtrip.dmarc_pass` | `1` pass, `0` anything else; missing when the header has no verdict. |
| `roundtrip.spam_score` | The receiving filter's score, when a known header carries one. |
| `roundtrip.virus_scanned` | `1` when a virus scanner marked the message. |
| `roundtrip.hops`, `roundtrip.max_hop_delay_ms`, `roundtrip.all_hops_tls` | Relay hops, the slowest hop, `1` when every hop was encrypted. |
| `roundtrip.error_count` | `1` when the check failed. |
| `roundtrip.smtp_connect_ms`, `roundtrip.smtp_tls_ms`, `roundtrip.smtp_auth_ms`, `roundtrip.send_ms`, `roundtrip.receive_auth_ms`, `roundtrip.check_time_ms` | Stage timings and the whole check. |

## Credentials

Both passwords, sending and receiving, are handled like the
[IMAP](/docs/monitors/imap#credentials) password: encrypted at rest
(AES-256-GCM) and bound to this monitor, write-only (API and MCP return
`"[redacted]"`; never in results, errors, logs, exports or the activity
log), kept when you leave the field as is on edit, and only ever sent over
an encrypted connection. The sending login is never attempted without TLS:
in STARTTLS mode the check stops if the server doesn't offer the upgrade.
Changing either side's server, port, encryption or username (or turning its
certificate check off) asks for that side's password again, so a saved
password never follows the monitor to another server.

## Also via API

Create with `type: "email_roundtrip"` (config: `smtpPort`, `smtpTlsMode`,
`smtpVerifyTls`, `smtpUsername`, `smtpPassword`, `fromAddress`, `toAddress`,
`receiveProtocol`, `receiveHost`, `receivePort`, `receiveTlsMode`,
`receiveVerifyTls`, `receiveUsername`, `receivePassword`,
`receiveSameCredentials`, `mailbox`, `checkSpamFolder`,
`deliveryTimeoutSeconds`, `deleteAfter`, `timeoutSeconds`). See the type
catalog for [Email round-trip](/docs/api/monitor-types#email-round-trip).

---

Canonical page: https://watchfor.io/docs/monitors/email-round-trip · All docs: https://watchfor.io/docs · Site guide: https://watchfor.io/llms.txt
