Back to Documentation

Email Integration

Connect a support mailbox over IMAP/SMTP and let your chatbot answer customer emails.

Connect a mailbox

Go to Dashboard → Channels → Email. The email channel reads new mail with IMAP and sends replies with SMTP, so it works with Gmail / Google Workspace, Yahoo, Fastmail, Zoho and most self-hosted servers. You need:

  • The mailbox address (for example support@yourcompany.com) and an optional display name.
  • IMAP host and port (usually 993 with SSL/TLS) and the login.
  • SMTP host and port (usually 587 with STARTTLS, or 465 with SSL/TLS) and the login.
  • A chatbot. Replies are generated from the chatbot's knowledge base and persona, so the channel cannot be created without one. Train the chatbot first.

Use Test connection before saving: it logs in to both servers and reports the exact IMAP and SMTP result. Saving also verifies both connections, then starts the sync. From that moment the channel only processes mail that arrives after it was connected. Existing mail in the inbox is never read or auto-replied.

TLS certificates are verified. For self-hosted servers with a self-signed certificate, tick Allow self-signed certificates. Mail is left unread in the mailbox unless you enable Mark emails as read after processing.

Outlook.com / Microsoft 365: Microsoft has turned off basic-auth IMAP for most tenants and OAuth sign-in is not supported here yet, so these mailboxes usually fail with an authentication error. Forward the mailbox to a Gmail/Workspace account or deliver mail through the inbound webhook instead.

App passwords

Providers with two-factor authentication do not accept your normal password for IMAP/SMTP. Create an app password instead:

Gmail / Google Workspace

  1. Enable 2-Step Verification under Google Account → Security.
  2. Open Security → 2-Step Verification → App passwords and create one (name it "AgentPro").
  3. Use the 16-character code as both the IMAP and the SMTP password.
  4. Make sure IMAP is enabled: Gmail → Settings → See all settings → Forwarding and POP/IMAP.
  5. Hosts: imap.gmail.com:993 (SSL/TLS) and smtp.gmail.com:587 (STARTTLS).

Yahoo

Account Security → Generate app password. Hosts: imap.mail.yahoo.com:993 and smtp.mail.yahoo.com:587.

Passwords are encrypted at rest and never returned by the API. When editing a connection, leave the password fields empty to keep the stored values.

What gets auto-replied

Every new inbound email is stored on a thread and mirrored into the unified inbox. The AI only replies when all of these hold:

  • The channel has a chatbot linked.
  • The email arrived after the mailbox was connected.
  • It is not automated mail (see loop protection below).
  • AI is still enabled on the conversation. A human reply from the inbox or the thread view pauses the AI for that conversation.
  • The thread is not resolved or marked as spam.
  • Nobody replied on the thread between the email arriving and the delay ending, and no newer email superseded it.
  • Rate limits are respected: at most 1 AI reply per thread every 10 minutes and 3 AI replies per sender per 24 hours.

The response delay gives your team time to answer first. Replies are scheduled as background jobs, so they survive a restart and are re-checked right before sending.

Before the message reaches the AI, quoted text ("On … wrote:", lines starting with >, forwarded header blocks) and signatures are stripped so only the new text is answered. The previous emails on the thread (last 10) are provided as context. The answer is sent as a proper reply (Re: subject, In-Reply-To/References headers), to the Reply-To address when present, with everyone else on the original email in CC, and your signature appended.

Loop protection

Automatic replies to automatic mail create infinite loops. These messages are stored but never answered:

  • Auto-Submitted header other than no, Precedence: bulk/list/junk/auto_reply, X-Autoreply, X-Autorespond, X-Auto-Response-Suppress.
  • Mailing list mail (List-Id, List-Unsubscribe).
  • Senders such as no-reply@, noreply@, mailer-daemon@, postmaster@, bounce@, notifications@, and mail from the connected address itself.
  • Delivery reports (multipart/report) and subjects starting with "Automatic reply", "Out of office", "Undeliverable", "Delivery status".

Every AI reply is sent with Auto-Submitted: auto-replied, X-Auto-Response-Suppress: All and Precedence: auto_reply, so other auto-responders stay quiet too.

Draft / review mode

Turn off Send AI replies automatically to review every answer. The AI still writes a reply, but saves it as a draft on the thread and marks the thread Needs review. Open Channels → Email → Threads to approve and send it, edit it first, or write your own reply.

Even with auto-reply on, answers with a low quality score (below 50%) are saved as drafts instead of being sent. A manual reply discards pending drafts.

Threads and the inbox

Emails are grouped into threads by In-Reply-To and References headers, falling back to the same sender and subject within 7 days. Each thread is linked to a conversation in the unified inbox, so agents can read and answer email next to chat and WhatsApp. Inbound mail appears as a visitor message, AI replies as bot messages and manual replies as agent messages.

Marking a thread resolved resolves the conversation; a new email from the customer reopens both. Attachments up to 10 MB each (25 MB per message) are stored and downloadable from the thread view.

Inbound webhook (alternative to IMAP)

If your mail provider or forwarding service can POST JSON, you can deliver mail without IMAP. Requests are authenticated with an HMAC-SHA256 of the raw request body using the channel's webhook secret (shown on the channel), sent as hex in the X-AgentPro-Signature header. Unsigned or mis-signed requests are rejected.

POST /api/v1/webhooks/email/<channelId>/inbound
Content-Type: application/json
X-AgentPro-Signature: <hex HMAC-SHA256(webhookSecret, raw body)>

{
  "from": "Jane Doe <jane@example.com>",
  "to": ["support@yourcompany.com"],
  "cc": [],
  "subject": "Order #1234 not delivered",
  "text": "Hi, my order has not arrived yet...",
  "html": "<p>Hi, my order has not arrived yet...</p>",
  "messageId": "<abc123@example.com>",
  "inReplyTo": null,
  "references": [],
  "headers": { "auto-submitted": "no" }
}

from and text or html are required. to, cc, references accept arrays or comma-separated strings. Include the original headers when you can so loop protection works. The webhook feeds the same pipeline as IMAP (threading, inbox mirror, auto-reply rules). Replies are still sent through the channel's SMTP settings.

const crypto = require('crypto');
const body = JSON.stringify(payload);
const signature = crypto
  .createHmac('sha256', process.env.AGENTPRO_WEBHOOK_SECRET)
  .update(body)
  .digest('hex');

await fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-AgentPro-Signature': signature,
  },
  body,
});

Delivery events for outgoing replies can be posted to the events endpoint. Bounces are recorded on the email.

POST /api/v1/webhooks/email/<channelId>/events
X-AgentPro-Signature: <hex HMAC-SHA256(webhookSecret, raw body)>

[
  { "event": "bounce", "messageId": "<reply-id@yourcompany.com>", "reason": "550 mailbox unavailable" },
  { "event": "delivered", "messageId": "<reply-id@yourcompany.com>" }
]

Troubleshooting

  • "IMAP connection failed: Invalid credentials" – use an app password, check that IMAP is enabled for the account, and confirm the username is the full email address.
  • "self signed certificate" – the server's certificate is not trusted. Fix the certificate or enable Allow self-signed certificates for internal servers.
  • "No chatbot linked" shown as the last sync error – emails are stored but not answered. Pick a chatbot in the auto-reply settings.
  • Replies are not sent – check the thread: the email may have been flagged as automated, rate limited, saved as a draft, or AI may be paused on the conversation after a human reply. The last sync error on the channel page shows SMTP failures.
  • Sync shows "Reconnecting" – the IMAP connection dropped; it reconnects automatically with backoff and polls on the configured interval in the meantime.