IMAP Client Setup
Plug Mailhooks into any tool that only speaks IMAP — legacy helpdesks, old ticketing systems, internal scripts, compliance archivers. No webhooks, no code changes.
Why IMAP
Mailhooks already exposes inbound email via a modern HTTP API, webhooks, and real-time SSE. But plenty of software out there still only speaks IMAP — and rewriting it isn't on the roadmap.
Point those tools at imap.mailhooks.dev and they start receiving mail through the same infrastructure as the rest of your stack — SPF/DKIM/DMARC checked, attachments in S3, retention managed, search indexed — without any of them knowing it isn't an ordinary mailbox.
Typical fit: osTicket, legacy Jira Service Desk, Mantis Bug Tracker, Request Tracker, internal Python imaplib scripts, old DMS/ERP mail-import workers, compliance archivers, and that one 15-year-old VB.NET tool nobody wants to touch.
Connection Details
| Host | imap.mailhooks.dev |
| Port | 993 |
| Security | SSL/TLS (implicit) |
| Authentication | LOGIN or AUTHENTICATE PLAIN |
| Username | *@yourdomain.com or [email protected] |
| Password | Your Mailhooks API key (must include the IMAP scope) |
| Mailbox | INBOX (single folder — flat stream of received mail) |
Create an IMAP-Scoped Key
IMAP access is gated by a scope on the API key. Existing HTTP API keys do not grant IMAP access by default — you opt in explicitly when you create the key.
- Go to Dashboard → API Keys → Create.
- Pick the environment whose domain you want to open over IMAP.
- Under Scopes, tick IMAP access. You can leave API access unchecked if this key is only for the mail client — a pure IMAP key can't call the HTTP API.
- Copy the
mh_…key — you'll paste it into the client's password field.
Treat the key like a password. Rotating it is as simple as creating a new key and deleting the old one — no coordination with the client vendor required.
Username Format
The IMAP username doubles as a filter over your inbox. You pick one of two patterns depending on how broad you want the mailbox to be.
*@yourdomain.comyourdomain.com shows up in the inbox. Use this when the downstream tool wants to see everything.[email protected]To list. Good for per-tool isolation: one key per downstream system, each scoped to its own address.The domain must be verified and owned by the same tenant and environment as the API key — Mailhooks refuses any mismatched combination at LOGIN with a generic "Authentication failed" response.
Client Setup
Four worked examples covering the common categories: a GUI mail client, two scripting libraries, and a raw socket session for when you're debugging a legacy tool with no visible IMAP settings.
Add a new account with manual configuration:
| Account type | IMAP |
| Server | imap.mailhooks.dev |
| Port | 993 |
| Connection security | SSL/TLS |
| Authentication | Normal password |
| Username | *@yourdomain.com |
| Password | mh_… (your API key) |
Thunderbird asks for an outgoing (SMTP) server too. Either point it at your real sending provider (SendGrid, Postmark, SES) or leave it blank — Mailhooks is inbound-only.
Supported Commands
Mailhooks implements the IMAP4rev1 subset that real clients and scripting libraries actually use. Anything not in this list is either rejected cleanly or advertised as unsupported during CAPABILITY.
| Command | Behaviour |
|---|---|
CAPABILITY | Advertises IMAP4rev1 AUTH=PLAIN AUTH=LOGIN UIDPLUS IDLE |
LOGIN / AUTHENTICATE PLAIN | Username + API key. SASL-IR is supported. |
LIST / LSUB | Returns a single mailbox, INBOX |
SELECT / EXAMINE / STATUS | Opens INBOX and reports MESSAGES, UNSEEN, UIDNEXT, UIDVALIDITY |
FETCH / UID FETCH | FLAGS, INTERNALDATE, RFC822.SIZE, ENVELOPE, BODY[], BODY[HEADER], BODY[TEXT], BODY.PEEK[...], BODY[HEADER.FIELDS (...)] |
STORE / UID STORE | +/- FLAGS \Seen and +/- FLAGS \Deleted |
SEARCH / UID SEARCH | ALL, SEEN, UNSEEN, FROM, TO, SUBJECT, SINCE, BEFORE, HEADER |
EXPUNGE / CLOSE | Permanently deletes messages marked \Deleted. Same as deleting from the Mailhooks dashboard. |
IDLE | Push notification — the server sends * N EXISTS in real time when new mail arrives. Send DONE to exit. Most clients re-issue IDLE automatically every 29 minutes. |
NOOP / CHECK / LOGOUT | Standard housekeeping. |
Security Model
- Scope enforcement. API keys without the IMAPscope are rejected at
LOGIN. HTTP-only and IMAP-only keys are cleanly separated. - Tenant + environment isolation. A key can only open domains owned by its own tenant and belonging to its own environment (production/staging/etc.).
- TLS required. Port 993 is implicit SSL/TLS. Plain
LOGINover a non-TLS socket is refused in production. - Uniform error. All auth failures return the same
NO Authentication failedresponse so clients can't probe which check (scope / tenant / domain / password) rejected them. - No outbound SMTP. Mailhooks is inbound-only — IMAP clients configured for Mailhooks cannot send mail through it.
Limitations
The IMAP surface is deliberately scoped to what legacy tools actually use. Things you won't find:
- Single folder. Every mailbox exposes only
INBOX. No custom folders, no Gmail-style labels. - No
\Flagged,APPEND,COPY,MOVE. Mailhooks is inbound-only, so creating or moving messages doesn't apply. - No threading extensions (
THREAD,SORT). Messages are returned in received order.
Troubleshooting
"Authentication failed"
Check three things in order:
- The key has the IMAPscope (edit the key in the dashboard).
- The domain in the username is owned by the same tenant and environment as the key.
- The key hasn't been deactivated or expired.
The error deliberately doesn't say which one failed — if you need a hint, try openssl s_client with one variable changed at a time.
"LOGIN requires TLS"
Your client is connecting with STARTTLS or plaintext on port 143 instead of implicit TLS on port 993. Change the port to 993 and the security mode to SSL/TLS.
Empty inbox when you expect mail
Usernames are case-insensitive but address-exact. If you log in as [email protected] and the mail was sent to [email protected], it won't appear. Switch to *@yourdomain.com to confirm the mail is landing, then narrow the filter.
Client shows "folder does not exist" for Sent / Drafts / Trash
Mailhooks exposes only INBOX. In Thunderbird / Apple Mail set the special folders to "(None)" or "On This Computer" so they don't try to auto-create remote folders.