Receive email over IMAP
Turn inbound email into conversations without exposing a public webhook.
Not every self-hosted deployment can expose a public webhook endpoint for inbound email. IMAP polling gets you the same result (visitor replies land as conversation messages) by having Quackback poll a mailbox instead of a provider pushing to you.
Note:
This page covers the self-hosted IMAP transport. For the concepts behind the email channel (threading, agent replies, routing) see Email channel.
IMAP vs. the provider webhook
Quackback supports two ways to receive inbound email:
Provider webhook | IMAP polling | |
|---|---|---|
Setup | Configure a provider (e.g. Resend inbound) and point its webhook at your instance | Point Quackback at any mailbox you already control |
Requires | A public HTTPS endpoint reachable from the provider | Outbound access to your IMAP host only |
Latency | Near-instant | Up to ~60 seconds (poll interval) |
If your instance isn't publicly reachable, or you already have a support mailbox and don't want to route it through a third-party inbound-email provider, use IMAP.
Configure the poller
Set these variables and restart:
EMAIL_INBOUND_PROVIDER=imap
IMAP_HOST=imap.example.com
IMAP_PORT=993
[email protected]
IMAP_PASSWORD=your-mailbox-password
IMAP_TLS=true
IMAP_MAILBOX=INBOXVariable | Default | Notes |
|---|---|---|
| unset | Must be |
| required | No default |
|
| |
| required | No default |
| required | No default |
|
| Set to |
|
| Mailbox to poll |
Warning:
EMAIL_INBOUND_PROVIDER,IMAP_HOST,IMAP_USER, andIMAP_PASSWORDare all required together. Leave any one unset and the poller never connects. There's no error, it just stays off.
How it works
A background worker polls the mailbox for unseen messages roughly every 60 seconds, parses each one, and creates or threads it into a conversation. Messages that ingest successfully, or are deliberately dropped as spam or unroutable, are marked seen. A message that fails to ingest (a transient error) is left unseen so the next poll retries it.
Tip:
The poller only runs on a replica whereQUACKBACK_ROLEisworkerorall. If you've split web and worker replicas, make sure a worker replica is running or inbound mail never gets picked up.
Replies from your team route back to the visitor by matching the In-Reply-To/References threading chain. If you also configure EMAIL_INBOUND_DOMAIN and EMAIL_INBOUND_SIGNING_SECRET for the webhook path, replies additionally route by plus-address. The two inbound methods aren't mutually exclusive.
Verify it works
Send a test email to the configured mailbox, then check that it appears as a new conversation within about a minute. If it doesn't:
- Confirm
QUACKBACK_ROLEisn'twebon every replica - Check the logs for
imap inbound not configured(means a required variable is missing) or a connection error - Confirm the conversations channel is enabled in Admin > Settings > Channels
Next steps
- Environment Variables - Full IMAP and email variable reference
- Scale with multiple replicas - Make sure a worker replica is running
- Troubleshooting - Fix IMAP mail that isn't creating conversations
Was this helpful?
Your feedback shapes what we write next.