Webhook notification
React quickly when the provider can reach the service.
Latency is only the visible difference. The real choice is who owns waiting, retries, duplicate delivery, authentication, recovery, and the state that connects an email to an active task.
Use bounded polling or a provider-supported wait operation for short-lived CLI, CI, and browser tasks that already have an active process and need one message. Use webhooks for persistent services that must react to many asynchronous messages without keeping workers open. Keep idempotent processing and a reconciliation query in either design. A webhook can be delayed or delivered more than once; polling can miss filters, hit rate limits, or stop before delayed mail arrives. The most reliable production design often uses webhooks for fast notification and mailbox queries for recovery.
The event makes the system fast; durable mailbox state makes it recoverable.
Store the message and assign a stable identifier before notifying consumers.
Deliver a signed webhook or event containing bounded metadata.
Queue work and reject repeated state transitions for the same event.
Query messages after the last stored cursor when delivery is uncertain.
A Playwright test has a live process, a known trigger, and a deadline. It can wait for one matching message and stop. Adding a public webhook endpoint, queue, correlation store, and cleanup job may create more failure modes than it removes. A bounded wait operation or polling loop is usually the smaller design.
A support agent service or workflow engine may run for months and receive messages when no initiating process is alive. Polling every mailbox from every worker wastes requests and complicates concurrency. A verified webhook that writes to a durable queue is a better notification mechanism, as long as the mailbox or event store remains available for recovery.
The choice should follow process lifetime and workload shape, not a blanket claim that webhooks are modern or polling is simple. Both require explicit state.
| Workload | Preferred starting point | Reason |
|---|---|---|
| One OTP in a browser test | Bounded wait or polling | The caller is active and knows the recipient and trigger time |
| Many long-lived agent inboxes | Webhook plus queue | Messages arrive independently of request sessions |
| Local CLI task behind NAT | Polling | No public callback endpoint is required |
| Workflow with strict recovery need | Webhook plus reconciliation | Fast reaction and durable catch-up both matter |
Record the trigger time before the external action. Query the intended mailbox and direction for messages received afterward, with sender or subject context where reliable. Keep the page size small. If there is no match, back off with jitter and continue until the deadline. If there are several valid candidates, return ambiguity instead of choosing the newest globally.
A dedicated wait-for-code operation can package these rules and return a narrow result. The caller should still assert that the code or link changed the outside application state. Receipt and extraction are intermediate evidence.
Persist a cursor or last processed message ID when polling a long-lived mailbox. Without one, a restart can reprocess old mail or require repeatedly scanning the whole history. Use provider timestamps carefully because delivery order and original sent time can differ.
The public endpoint should verify the signature or provider authentication, validate basic envelope shape, store or enqueue the event, and respond quickly. It should not run a long model call, download every attachment, or perform a fragile external action before acknowledgement. Slow handlers increase retries and duplicate work.
Use a stable event or message identifier as the idempotency key. The first consumer transition can claim the event; later deliveries should observe the recorded state and stop. If the provider does not supply a reliable identifier, derive a bounded fingerprint from mailbox, message headers, and payload metadata while retaining the original event for diagnosis.
A valid webhook proves that the event came through the expected transport path. It does not make the email body, links, or requested action trustworthy. Apply workflow eligibility and content policy after transport verification.
Check signature, timestamp tolerance, route, and expected event type.
Write an event record or queue message before acknowledging.
Allow one consumer to advance the workflow for the event.
Validate sender context, links, files, and action authority.
Webhooks can fail because DNS, certificates, signatures, deploys, queues, or handlers fail. Polling can fail because a process ends, a filter is wrong, or rate limits intervene. A hybrid design treats the webhook as a prompt to inspect durable mailbox state, not as the only copy of the message.
Store the last reconciled cursor per mailbox or workflow. On startup and on a schedule, query messages after that cursor and enqueue anything not already processed. The same idempotent consumer handles webhook and reconciliation events. This prevents two separate business paths from drifting.
React quickly when the provider can reach the service.
Retrieve current message state under scoped authorization.
Recover events after downtime without replaying the entire inbox.
Record message ingestion time, notification attempt, endpoint acknowledgement, queue availability, consumer start, business transition, and final application outcome. A single end-to-end latency number cannot tell the team whether transport, notification, queueing, model work, or the external system caused the delay.
Alert on a rising webhook retry rate, reconciliation gaps, old unprocessed messages, repeated ambiguity, and polling rate limits. Keep bodies, OTPs, addresses, and secrets out of broad telemetry. Use message and workflow identifiers that operators can resolve through restricted tools when investigation is necessary.
| Metric | Meaning | Useful response |
|---|---|---|
| Ingest to notify | Provider or internal event delay | Inspect event production and routing |
| Notify to acknowledge | Endpoint availability and load | Inspect signature and queue path |
| Acknowledge to process | Queue and worker delay | Scale or repair consumer |
| Process to outcome | Application or external action delay | Inspect workflow state and policy |
Use the simplest wait mechanism that fits the caller lifetime. For persistent systems, send verified notifications into an idempotent queue and keep a mailbox cursor for repair. This design remains understandable when messages are delayed, delivered twice, or arrive while the service is down.
Product behavior is verified against the mails0 source and documentation. External comparisons link to official vendor documentation checked on 2026-08-15.
No. A bounded CLI, CI, or browser task often benefits from polling or a wait operation. Persistent services with many asynchronous inboxes usually benefit from webhooks plus durable processing.
Use provider guidance, exponential backoff with jitter, a small result limit, and a total deadline. Avoid a fixed aggressive interval across many parallel workers.
Keep durable message state and reconcile from a stored cursor. Feed recovered messages through the same idempotent consumer used by webhook events.
Start with one scoped inbox and one expected message. Add durable identity, sending, and operational complexity only when the first loop works.