Test Emails with Mailtest
Mailtest captures outbound email from your dev and staging environments so you can preview it without sending to real recipients. Think of it as a safety net for email templates, password resets, and any Odoo flow that normally fires mail.
What Is Mailtest?
When you enable Mailtest on an environment, we:
- Generate unique SMTP credentials for that environment.
- Configure your Odoo to send all outbound email to our capture server (
mail-smtp.oec.sh). - Store captured email in a preview inbox accessible from your dashboard.
- Automatically purge old mail per your plan's retention window.
You get full fidelity: HTML, plain text, headers, raw source, and attachments — sandboxed for security so malicious content in a template can't hit your browser.
Mailtest is designed for development and staging environments. It cannot be enabled on production — the platform blocks it to protect your real customers.
Who Is It For?
- Developers iterating on email templates (invoice, welcome, password reset)
- Agencies managing multiple client projects who need confidence that email flows work before handing over
- QA teams who want to verify email behavior without burning real recipient addresses
- Anyone tired of using fake SMTP credentials or self-hosted MailHog containers
Step 1: Enable Mailtest on an Environment
Open the Environment
- Go to Environments in the sidebar
- Click the environment you want to test with (must be dev or staging)
Open the Mailtest Tab
Click the Mailtest tab in the environment header. If you don't see it, check that:
- Your plan is Starter, Pro, or Agency (not Free).
- You have the
project.mailtest.managepermission. - The environment is not marked as production.
Click "Enable Mailtest"
A consent modal appears explaining what we'll do to your Odoo's ir.mail_server configuration. The wording depends on your Odoo version:
- Odoo 17+: We disable your existing outgoing mail servers and add our capture server.
- Odoo 13–15: We rewrite your existing servers to route through the capture server, remembering the originals for restore on disable.
Read the modal, then click Enable Mailtest →.
Save Your Credentials
After ~3 seconds, a credential-reveal modal shows:
SMTP Host: mail-smtp.oec.sh
SMTP Port: 587
Encryption: STARTTLS
Username: org-xxxxxx-env-xxxxxx
Password: <shown once>The password is shown only once. Save it somewhere safe (password manager, .env file). You can rotate it anytime from the settings panel, but you can't recover the current one.
Click I've saved these, close — Odoo is already configured automatically; the credentials are for your own reference if you need to see them.
Step 2: Test Capture
Trigger an email from your Odoo:
- Request a password reset for any user.
- Send a test from an email template (Settings → Technical → Email Templates → Send Test).
- Create a quote or invoice that auto-sends an email.
Within ~5 seconds, the email appears in your Mailtest inbox at /dashboard/mailtest — no page refresh needed; we stream it live via SSE.
TODO: ship screenshot of inbox with captured message
Step 3: Using the Inbox
The inbox has a two-panel layout: list on the left, preview on the right. Five tabs for the preview:
| Tab | Shows |
|---|---|
| HTML | Rendered HTML body in a sandboxed iframe (images proxied for privacy) |
| Plain | Plain-text alternative (falls back to HTML-stripped if missing) |
| Headers | Full SMTP headers — useful for debugging From, Reply-To, Message-ID, List-Unsubscribe |
| Raw | Complete .eml source, copy-paste friendly |
| Attachments | Download individual attachments |
Keyboard shortcuts
| Key | Action |
|---|---|
j / k | Next / previous message |
h / l | Cycle preview tabs left / right |
/ | Focus the search box |
d | Delete current message (confirmation modal) |
? | Show shortcut help |
Search
The search box filters by subject, sender, recipient, or body content. Matches are case-insensitive.
TODO: ship screenshot of preview tabs
What We Changed in Your Odoo (for the curious)
Mailtest modifies the ir.mail_server table in your Odoo database. The exact approach depends on your Odoo version:
Approach C (recommended, supported by Odoo's _check_forced_mail_server guard):
- Insert a new
ir.mail_serverrow:smtp_host=mail-smtp.oec.sh,smtp_port=587,smtp_encryption=starttls,smtp_user=<generated>,smtp_pass=<generated>,active=true. - Set
active=falseon every otherir.mail_serverrow. - We snapshot the pre-change state so we can restore on disable.
If you have email templates with an explicit Outgoing Mail Server selected, those templates will fail with a visible "server cannot be used because it's archived" error — review and update them, or uncheck the explicit server to use the default.
On disable, we restore the snapshot exactly.
Rotating Credentials
From Environments → [your env] → Mailtest tab → Settings → Rotate credentials:
- Confirm the rotate modal. During rotation (~5 seconds) SMTP AUTH is temporarily blocked — in-flight sends retry on Odoo's mail queue (typically ~1 minute).
- A new password is revealed once, same as enable.
- Your Odoo's
ir.mail_serveris updated in-place; no action needed on your side.
If rotation gets stuck (rare — usually a transient Odoo DB connection issue), you'll see a "Rotation in progress" banner with Retry and Abort buttons. Retry regenerates a fresh password (idempotent); Abort clears the flag and keeps the old credentials active.
Disabling Mailtest
From Environments → [your env] → Mailtest tab → Settings → Disable Mailtest:
- The confirmation modal shows how many captured emails will be kept for how long under your current plan.
- You can optionally download all captured mail as a
.zipbefore disabling (async export with a 7-day signed URL; emailed when ready). - Click Confirm Disable.
On disable:
- Your Odoo's
ir.mail_serveris restored to its pre-Mailtest state (marker row removed on Odoo 17+; originalsmtp_hostvalues restored on Odoo 13–15). - Mail capture stops immediately; the credentials are invalidated.
- Captured mail remains accessible for the plan retention window (30 / 90 / 365 days), then is automatically purged.
Data Retention
| Plan | Retention | Message cap | Storage cap |
|---|---|---|---|
| Starter | 30 days | 1,000 messages | 100 MB |
| Pro | 90 days | 10,000 messages | 1 GB |
| Agency | 365 days | 100,000 messages | 10 GB |
| Free | — | Not available | — |
Caps are per organization across all environments. When you hit a cap:
- Message cap: the oldest messages are purged hourly to stay under limit.
- Storage cap: same as message cap — oldest first.
- During normal operation: caps are almost never hit; 100 MB stores ~3,000 typical text+HTML emails.
Plan downgrade grace
If you downgrade from Pro to Starter, your retention shortens from 90 days to 30 days — but we give you a 14-day grace period before enforcement. A banner shows the deletion-start date, and you can download all mail or upgrade back in that window.
FAQ
Does Mailtest support Odoo 13, 14, 15, 16, 17, 18, and 19?
Yes. Versions 17+ use Approach C (marker row + disable others); versions 13–15 use Approach D (rewrite in place with restore-on-disable). Version 16 uses Approach C. See "What We Changed in Your Odoo" above.
My email template has an explicit Outgoing Mail Server selected. What happens?
On Odoo 17+ (Approach C): the template will fail with "server cannot be used because it's archived." You'll see a visible error. Fix: either uncheck the explicit server (so it uses the default, which is our marker row), or update the template to point at the marker row.
On Odoo 13–15 (Approach D): the template still works — we've rewritten all servers to point at the capture endpoint, so even an explicit selection routes correctly.
Can I enable Mailtest on production?
No. The platform blocks Mailtest on any environment flagged as production. This is enforced both in the UI (button disabled) and at the API level (backend returns 403).
What happens to my captured email if I downgrade my plan?
On downgrade, your retention shortens to the new plan's window. We give you 14 days of grace before the shorter retention takes effect — use that window to download anything you want to keep (Settings → Download all as .zip).
Is my captured email private? Can oec.sh staff see it?
Captured email is stored encrypted at rest in Cloudflare R2 (EU jurisdiction) and our Postgres database (Hetzner Falkenstein). Only users in your organization with the project.mailtest.view permission can read it via the dashboard. Internal access by oec.sh staff is audit-logged and restricted to break-glass incident response. See our Privacy Policy (opens in a new tab) and DPA Exhibit M (for customers with a signed DPA).
Can I export my captured mail?
Yes. From the Mailtest tab on any environment → Settings → Download all as .zip. The export is generated asynchronously and delivered via a 7-day signed URL emailed to you.
What about spam scoring / HTML compatibility analysis?
Deferred to v1.1. For v1, we focus on reliable capture + preview. Spam scoring (SpamAssassin integration) and HTML cross-client check (Outlook / Gmail / Apple Mail preview renders) are planned but not yet shipped.
Troubleshooting
535 5.7.8 Authentication failed
The SMTP username or password is wrong. Common causes:
- You rotated credentials but Odoo is still using the old password. Fix: re-run the enable flow, or edit
ir.mail_servermanually with the new password from the Mailtest settings panel. - The credentials belong to a different environment. Each environment has its own.
421 4.7.0 Rejected: AUTH required / 421 4.3.2 Service shutting down
The SMTP server is rejecting AUTH, usually because:
- During rotation: the
is_rotatingflag blocks AUTH for ~5 seconds. Odoo retries automatically within ~1 minute. - During platform kill switch: oec.sh has disabled Mailtest platform-wide (very rare; we'd notify you first). Check the dashboard for a banner.
- IP banned: your Odoo's outbound IP has repeatedly failed authentication. The ban clears after ~15 minutes. If it recurs, check that the SMTP credentials in Odoo match the ones in Mailtest settings.
452 4.3.1 Insufficient system storage / 552 5.3.4 Message exceeds fixed maximum message size
You've exceeded a cap:
- 452 = message count or storage quota for your organization. Upgrade your plan or clear the oldest messages.
- 552 = individual message is larger than the per-message limit (10 MB on Starter, 25 MB on Pro, 50 MB on Agency). Reduce attachment size or upgrade.
"I can't see the email I just sent"
Check, in order:
- Is Mailtest enabled on the sending environment? (Dashboard → Environments → [env] → Mailtest tab)
- Is the environment actually using our SMTP server? Inspect
ir.mail_serverin Odoo — the active row should havesmtp_host=mail-smtp.oec.sh. - Did Odoo actually send? Check Odoo's own mail queue (Settings → Technical → Email → Emails).
- Wait 10 seconds and refresh — SSE should have delivered it within 5s, but in rare cases a fresh page load pulls from the paginated list.
- Check for a Tamper detected banner — if something (a script, another user,
neutralize) modified their.mail_serverrow, Mailtest stops accepting mail from that env until you re-enable.
"Tamper detected" banner
Someone or something modified the ir.mail_server row Mailtest is expecting — we detect this at AUTH time. Causes:
- A backup restore that brought back pre-Mailtest state.
- A neutralize operation (we re-inject on neutralize, but if you manually tweaked settings after, that breaks the marker).
- A
pg_restoreor custom script.
Fix: click Re-enable to fix on the banner. It runs the enable flow again and resets the marker row.