Skip to content
cd ..

Real Time Email Notifications with Server Sent Events

// · 5 min read

Polling is the easy way to check for new email. Set a timer, call the API every few seconds, see if anything arrived. It works, but it’s wasteful and slow. An agent polling every 10 seconds might wait up to 10 seconds after a message arrives before it knows about it. Multiply that by a fleet of agents and you have a lot of unnecessary API calls.

AgenticMail uses Server Sent Events (SSE) to push email notifications to agents the moment they arrive. One persistent HTTP connection, server pushes events down it, the agent reacts immediately.

The events route

The entire real time system is a single endpoint in the events route module. An agent opens a GET request to the events endpoint with its bearer token, and the server holds the connection open. The response uses text/event-stream content type, and the server writes events to it as they occur.

SSE was the right choice over WebSockets for this use case. The communication is one directional: the server pushes events to the agent. The agent doesn’t need to send messages back over the same connection. SSE works over plain HTTP, passes through proxies and load balancers without special configuration, and reconnects automatically if the connection drops. WebSockets would add complexity (upgrade handshake, ping/pong keepalive, bidirectional framing) for no benefit.

IMAP IDLE under the hood

The real time magic comes from IMAP IDLE. When an agent connects to the SSE endpoint, the server opens an IMAP connection to the agent’s mailbox and issues the IDLE command. IMAP IDLE tells the mail server to push notifications when the mailbox state changes, rather than requiring the client to poll with repeated SEARCH commands.

When a new message arrives in the mailbox, the IMAP server sends an EXISTS notification over the idle connection. AgenticMail’s event system receives this, fetches the message metadata (sender, subject, date, size), and pushes an SSE event to the agent.

The mapping is one to one. Each SSE connection has a corresponding IMAP IDLE connection to the agent’s mailbox. When the SSE connection closes, the IMAP connection closes too. No orphaned connections sitting idle on the mail server.

Inline spam filtering

Before a new email event gets pushed to an agent, the message passes through the spam filter. This happens inline during event delivery, not as a separate background job.

The spam filter evaluates header anomalies, sender reputation (against local blocklists and allowlists), content heuristics, and known spam signatures. Messages that score above the spam threshold get tagged as spam and the SSE event includes the spam classification. The agent can decide whether to ignore it, quarantine it, or process it anyway based on its own policies.

Running the spam filter inline means agents never receive an unclassified message. Every new email event arrives with a spam verdict already attached. There’s no window where an agent might process a spam message before the background filter gets to it.

Rule evaluation

Email rules also run inline during event delivery. If an agent has configured rules like “move messages from this sender to this folder” or “auto reply to messages containing this keyword,” those rules execute before the event reaches the agent.

This means the SSE event the agent receives reflects the post rule state. If a rule moved the message to a specific folder, the event includes the destination folder. If a rule added a label, the label is already applied. The agent sees the final state, not a raw pre rule state that it would need to reconcile.

Rules that trigger auto replies happen transparently. The agent gets a notification that a message arrived and was auto replied to. It can review the auto reply or take additional action, but the time sensitive response already went out.

SSE watchers for sub agents

The main agent in a multi agent setup can subscribe to SSE events for all of its sub agents through a single connection. Rather than each sub agent maintaining its own SSE connection, the main agent opens one watcher that multiplexes events from all subordinate mailboxes.

Each event includes the sub agent identifier, so the main agent can route the notification appropriately. This is more efficient than N separate connections, and it gives the main agent a single stream of all email activity across its fleet.

The main agent can also filter the watcher by sub agent, message type, or sender. If it only cares about high priority messages for a specific sub agent, it can specify that and ignore everything else. The filtering happens server side, so unnecessary events never consume bandwidth.

Graceful shutdown

When the server shuts down (for deployment, maintenance, or restart), it needs to close all active SSE connections cleanly. A hard disconnect would leave agents in a confused state, potentially missing events during the gap between disconnect and reconnect.

The shutdown sequence sends a special “closing” event to all connected agents, giving them a few seconds to acknowledge. Then it closes the SSE connections, which closes the underlying IMAP IDLE connections. Agents that implement proper SSE reconnection logic will reconnect automatically when the server comes back up and receive any messages that arrived during the downtime.

The closing event includes a timestamp so agents can request events from that point forward when they reconnect. No messages are lost; they’re just slightly delayed during the restart window.

Real time email delivery transforms how agents work with email. Instead of polling and hoping, they react. A customer email arrives and the agent responds in seconds. A verification code comes in and the agent captures it immediately. SSE makes that responsiveness possible with minimal infrastructure complexity.

Source Code

View the full source on GitHub

// share

// subscribe

New posts and updates straight to your inbox. No noise.

cd ..