Use webhooks when email must trigger reliable server-side work, WebSockets when an interactive agent needs live events without a public endpoint, and polling for scheduled checks or recovery. For most production agents, the safest design uses webhooks as the durable path and GET /messages for reconciliation. Add a WebSocket when a live interface or local agent needs immediate updates.
All three patterns can deliver the same basic outcome: the application notices a new message and gives it to the correct workflow. The difference is how events arrive, what happens during downtime, and how much infrastructure the application must operate.
Quick comparison
| Requirement | Webhook | WebSocket | Polling |
|---|---|---|---|
| New mail arrives without repeated reads | Yes | Yes | No |
| Public HTTPS endpoint required | Yes | No | No |
| Provider retries after downtime | Yes | No, live-only | Your scheduler retries |
| Best fit | Durable server-side processing | Interactive agents and live UIs | Scheduled work, local prototypes, reconciliation |
| Main failure mode | Slow or non-idempotent handler | Missed events while disconnected | Delay and repeated empty requests |
| Recommended production role | Primary processing path | Low-latency companion | Recovery and backstop |
SentFromAI documents inbound mail as parsed and threaded before delivery. Its receiving guide supports signed webhooks and polling with GET /messages. Its separate realtime guide streams the same event types over a WebSocket.
Choose webhooks for durable processing
A webhook is an HTTPS request from the email provider to your application. When a message arrives, the provider sends an event to a URL you registered.
This is the strongest default when an inbound email should create durable work, such as:
- opening or updating a support case;
- classifying an invoice;
- starting an approval workflow;
- recording a customer reply;
- drafting an in-thread response; or
- escalating a message to a person.
SentFromAI signs webhook deliveries with HMAC-SHA256 over the raw request body. The application should verify that signature, store or enqueue the accepted event, return a fast 2xx, and run model or tool work asynchronously.
Do not wait for an LLM call inside the webhook request. A slow handler can cause retries, and a retry can run the same agent action twice if the application has no idempotency guard. Track processing by event, message, or workflow identifier before sending a reply or changing another system.
The full implementation pattern is covered in Email to Webhook for AI Agents. The architectural rule is shorter:
- Verify the raw request.
- Route it to the correct inbox and tenant.
- Durably accept the event.
- Return
2xxquickly. - Process the message outside the request.
- Record the result before any retry can repeat the side effect.
Webhooks do require a reachable HTTPS endpoint. That is normal for a deployed service, but it can add friction for a local agent, desktop process, or short-lived development environment.
Choose WebSockets for live agents without a public endpoint
A WebSocket keeps one outbound connection open from the application to the provider. New events arrive over that connection without the application exposing an inbound URL.
That fits:
- an interactive agent running on a developer machine;
- a live operations dashboard;
- a desktop or gateway process that cannot accept public HTTP requests;
- a workflow where the user should see a new message immediately; or
- a low-latency companion to durable server-side processing.
SentFromAI’s documented connection is:
wss://api.sentfrom.ai/v1/realtime?token=sf_live_…
The socket emits the same event names used by webhooks, including message.received, message.delivered, message.bounced, message.complained, and message.rejected. Realtime frames place the event payload under data.
The tradeoff is durability. The current SentFromAI realtime stream is live-only and does not replay missed events after a disconnect. If the process loses its connection, it should reconnect and reconcile messages through the API. A socket-only worker that assumes every event was observed can silently miss work.
Use WebSockets when immediate interaction matters, but keep recovery explicit:
- Detect disconnects and reconnect with backoff.
- Record the last successfully processed message or timestamp in application state.
- After reconnecting, query recent messages for the affected inbox.
- Deduplicate anything already processed.
- Resume live event handling only after reconciliation starts or completes.
For critical workflows, pair the WebSocket with a webhook. The webhook owns durable processing, while the socket updates the live interface.
Choose polling for simplicity and recovery
Polling means the application calls the messages API on a schedule and asks for recent or matching mail. With SentFromAI, GET /messages can filter by inbox, limit the result, and search by keyword, semantic meaning, or a hybrid of both.
Polling is a sensible choice when:
- the agent checks mail every few minutes rather than immediately;
- the runtime cannot expose a public endpoint or hold a stable socket;
- the workflow runs as a scheduled job;
- a local prototype needs the smallest possible receive loop; or
- the application needs to reconcile after a webhook or socket problem.
The cost is delay and repeated reads. A one-minute interval can still be too slow for an interactive support workflow and unnecessarily frequent for a daily reporting agent. Choose the interval from the reader’s expectation, not from the easiest cron expression.
A polling worker also needs state. Store a cursor, time boundary, or set of processed message IDs. Without that boundary, every run either misses messages or repeatedly processes the same ones.
Do not treat search results as an ordered event log unless the API documents that behavior. Query a bounded window, deduplicate by message ID, and make the downstream action safe to retry.
The production pattern uses more than one mode
The three modes are not mutually exclusive. They solve different parts of the receive path.
A strong production architecture often looks like this:
| Layer | Responsibility |
|---|---|
| Webhook | Accept and durably enqueue every inbound event. |
| Worker | Fetch needed message or thread context, apply policy, and run the agent. |
| WebSocket | Update a live UI or interactive agent as events happen. |
| Polling reconciliation | Find anything missed during downtime and verify application state. |
This avoids asking one mechanism to do every job. Webhooks provide retried delivery. WebSockets provide immediate interaction without an inbound endpoint. Polling provides a recovery path controlled by your application.
If a webhook is not possible, combine WebSockets and polling. Let the socket handle normal low-latency events, then run a periodic message query and reconcile after every reconnect.
If low latency is not important, polling alone can be enough. A scheduled research agent that reads one mailbox every hour does not need a permanent socket merely because the option exists.
Preserve thread and application state separately
Receiving a new message is only the trigger. Before the agent acts, retrieve the conversation and the workflow state that explain what the message means.
Keep these records separate:
- Message state: sender, recipients, body, attachments, delivery status, and message ID.
- Thread state: ordered conversation, participants, earlier commitments, and thread ID.
- Application state: tenant, permissions, approvals, processing status, and external side effects.
The email threading guide explains how to preserve conversation context and reply through the existing message relationship. A receive loop that loses the thread can respond quickly and still respond incorrectly.
Treat every inbound email as untrusted content. A valid provider signature proves the event came through the configured delivery path. It does not make the message body an instruction the agent should obey. Apply tenant routing, tool permissions, output validation, and human approval before high-impact actions.
Decision checklist
Choose the primary mode by answering these questions:
- Must the workflow react in seconds, minutes, or hours?
- Can the runtime accept a public HTTPS request?
- Can it maintain a long-lived outbound socket?
- What happens to events while the application is offline?
- Which actions must be durable before the provider receives
2xx? - How will duplicate events be detected?
- How will missed events be reconciled?
- Does a live UI need updates separate from backend processing?
- Can the application retrieve the full thread before replying?
- Which messages require a draft or human approval?
If the answers are still unclear, start with a webhook and a reconciliation job. Add a WebSocket only when live interaction creates a real product benefit.
Start with one complete receive loop
Create one dedicated inbox, send a message to it from an address you control, and verify the whole path: receive the event, retrieve the message and thread, apply a simple policy, and produce a draft or reply. Then disconnect the live path and confirm the recovery mechanism finds the message.
SentFromAI provides programmatic inboxes for AI agents, signed webhooks, a realtime WebSocket, message search, and native threads. You can start free with 5 inboxes and 5,000 emails, then review current pricing before scaling the workflow.
Frequently asked questions
Are WebSockets more reliable than webhooks?
Not in the current SentFromAI delivery model. Webhooks are retried after non-2xx responses. The realtime WebSocket is live-only and does not replay missed events, so reconnecting clients should reconcile with GET /messages or use webhooks for durable processing.
Can an AI agent receive email without a public URL?
Yes. It can use the SentFromAI realtime WebSocket for live events or poll GET /messages. Use polling or API reconciliation to cover messages that may arrive while a WebSocket is disconnected.
Should an agent poll continuously?
Usually no. Use a webhook or WebSocket for low-latency work. Poll on a schedule when delay is acceptable, or use polling as a recovery and reconciliation path.
Should the agent run inside the webhook handler?
No. Verify and durably accept the event, return 2xx quickly, then run the agent asynchronously. This prevents slow model calls from blocking delivery and reduces duplicate side effects after retries.
Can the same application use all three modes?
Yes. A common pattern uses webhooks for durable processing, WebSockets for a live interface, and polling for reconciliation. Deduplicate by stable message or event identifiers so the same email does not trigger the action twice.
Sources
- SentFromAI: Receiving email, for webhook events, HMAC verification, retries, and polling.
- SentFromAI: Realtime WebSocket, for connection behavior, event frames, live-only delivery, and reconciliation guidance.
- SentFromAI API: Search messages, for inbox filtering and search modes.
- AgentMail: How to trigger an agent when email arrives, for a current provider example of raw-body verification and fast acknowledgement.
- Postmark: Inbound webhook, for a current provider example of parsed inbound email and webhook retries.