Should inbound email use polling or webhooks?
Choose from caller lifetime and recovery needs. Latency matters, but lost events, duplicates, rate limits, and operational state matter more.
Use bounded polling or a wait operation when a short-lived CLI, CI, or browser task is active and expects one specific message. Use webhooks when a persistent service must react to messages across many mailboxes without keeping request processes open. For production reliability, combine signed webhook notification with idempotent queue processing and a mailbox reconciliation query from a stored cursor. Never use an unbounded polling loop, and do not treat one webhook delivery as the only durable copy of an important message.
Workflow at a glance
Persist or queue before acknowledging
- 01Verify the event path
Check signature, timestamp, route, and expected event type.
- 02Write durable state
Store or enqueue the event before returning success.
- 03Claim idempotently
Allow one consumer transition for each message or event ID.
- 04Apply content policy
Treat email instructions, links, and files as untrusted.
Match the mechanism to the caller
| Caller | Start with | Reason |
|---|---|---|
| Playwright or CI test | Bounded wait | The process knows the trigger, recipient, and deadline |
| Local coding agent | Polling or wait tool | No public callback endpoint is needed |
| Persistent workflow service | Webhook and durable queue | Messages arrive outside request sessions |
| High-reliability service | Webhook plus reconciliation | Fast path and repair path are both explicit |
Use exact filters and backoff
Record the trigger time and query only the scoped mailbox for current messages that match the expected recipient, direction, sender context, and type. Use a small page size, exponential backoff with jitter, and a hard deadline.
Return ambiguity when several messages match. Repeatedly triggering the original action can create competing codes and make the wait less reliable.
Persist or queue before acknowledging
-
01
Verify the event path
Check signature, timestamp, route, and expected event type.
-
02
Write durable state
Store or enqueue the event before returning success.
-
03
Claim idempotently
Allow one consumer transition for each message or event ID.
-
04
Apply content policy
Treat email instructions, links, and files as untrusted.
Reconcile from mailbox state after downtime
Keep the last processed cursor per mailbox or workflow. On startup and at a scheduled interval, query messages after that cursor and enqueue anything that lacks a processing record. Use the same consumer as the webhook path.
Track ingestion, notification, acknowledgement, queue, processing, and final workflow times separately. This identifies which layer causes delay or loss without logging sensitive message content.
Sources and product scope
Product behavior is verified against the mails0 source and documentation. External comparisons link to official vendor documentation checked on 2026-08-15.
- mails0 source repositoryImplementation, license, and deployment source
- mails0 webhook documentationSigning, retries, and event handling
Related questions
Are webhooks faster than polling?
They can reduce reaction delay, but endpoint, queue, and retry behavior still matter. Measure the full path and keep reconciliation for recovery.
Can polling miss an email?
Poor filters, an expired process, pagination, or a short deadline can miss it. Use a stored cursor for long-lived polling and explicit current-message filters for bounded waits.
How do I prevent duplicate webhook processing?
Use a stable event or message ID as an idempotency key, persist state before side effects, and let repeated deliveries observe the completed or in-progress transition.
Prove the smallest useful email loop.
Start with one scoped inbox and one expected message. Add durable identity, sending, and operational complexity only when the first loop works.