<!-- Canonical: https://staging.startupmail.dev/guides/inbound-email-webhook-vs-persistent-mailbox -->
<!-- Last reviewed: 2026-08-25 -->

# Inbound email webhook vs persistent mailbox: which do you need?

> Compare inbound email webhooks with persistent mailboxes, including storage, threads, retries, human access, and the cases where you need both.

An inbound email webhook tells your application that a message arrived. A persistent mailbox
stores the message and the conversation so people and software can read it later.

Choose a webhook when email is only an event that starts a short process. Choose a mailbox
when the conversation has lasting value, someone may reply, or a person may need to inspect and
take over. Many useful systems need both: the webhook starts the work, and the mailbox remains
the source of truth.

## The difference at a glance

| Question                | Inbound email webhook                          | Persistent mailbox                    |
| ----------------------- | ---------------------------------------------- | ------------------------------------- |
| Main job                | Notify an application                          | Store and organize email              |
| Keeps message history   | Only if your application stores it             | Yes                                   |
| Holds complete threads  | Only if you build threading                    | Yes                                   |
| Gives people an inbox   | No                                             | Yes                                   |
| Gives prompt notice     | Yes                                            | Usually through a webhook or polling  |
| Handles webhook retries | Your application must deduplicate them         | Still required for event-driven work  |
| Supports later replies  | Only if you build and store the needed context | Yes, from the stored conversation     |
| Best fit                | Stateless processing and routing               | Ongoing conversations and shared work |

The two are not direct substitutes. One is a delivery mechanism for events. The other is
durable application state.

## What is an inbound email webhook?

An inbound email webhook is an HTTPS request sent when an email provider accepts a message.
The payload may include the sender, recipients, subject, message identifiers, body, and
attachment details. The exact shape depends on the provider.

The webhook lets your application react without polling. It can create a support ticket, pass
an invoice to a queue, update a CRM record, or alert an on-call team.

That speed is useful, but it can hide extra work. If the provider does not keep a mailbox, your
application must decide what to store. It may also need to parse MIME, store attachments, link
replies, build search, manage permissions, and give staff a way to inspect the original email.

## What is a persistent mailbox?

A persistent mailbox is the durable home of an email address. It stores accepted messages,
attachments, delivery state, and conversation threads. It remains useful after the first
notification has been processed.

A mailbox also gives people and software a shared reference point. A customer support agent can
open the same thread that an automated system classified. An AI agent can fetch the latest
messages before it drafts a reply. An operator can see whether someone else has already
answered.

In Startup Mail, accepted messages appear in the web inbox and become available through the
REST API, SDKs, and MCP tools, subject to the key's resource scope and permissions. Signed
webhooks notify an application when that state changes. Messages remain until a user deletes
the thread or workspace. Deleted threads stay in trash for 30 days before permanent removal.
Startup Mail does not currently publish a general storage quota. Read the
[storage and retention notes](https://staging.startupmail.dev/docs/usage-limits.md).

## When is a webhook enough?

A webhook can be enough when the email is a disposable input and your application already owns
the permanent record.

Good cases include:

- A service receives a one-time verification code and records only the result.
- A parser extracts a fixed field from a machine-generated message.
- A gateway converts each accepted email into a ticket, then all later work happens in the
  ticket system.
- A test environment checks whether a message arrived and discards it after the test.

Even here, decide what happens when parsing fails. Someone may need the raw message to diagnose
an unusual MIME structure, a missing attachment, or a damaged character encoding. If the
upstream provider removes the source soon after delivery, recovery may be hard.

## When do you need a mailbox?

Use a persistent mailbox when email remains part of the product or business record.

### The exchange may continue

A single inbound message often becomes a conversation. Replies use standard `Message-ID`,
`In-Reply-To`, and `References` headers to identify messages and threads.
[RFC 5322](https://www.rfc-editor.org/rfc/rfc5322.html) defines these fields.

If your application stores only the webhook payload, it must preserve enough headers and state
to create correct replies. A mailbox service does that work and keeps the resulting thread
together.

### A person may need to intervene

Automation fails at the edges. The message may be unclear, the sender may ask an unexpected
question, or the next action may need approval.

A stored mailbox lets a person read the original, review earlier replies, and continue from the
same address. Without one, you may need to build an internal inbox or copy the content into
another system.

### More than one process uses the email

One incoming message may trigger spam checks, classification, attachment processing, a
customer record update, and a draft reply. Passing the entire message between each service
creates copies and stale state.

A smaller event works better. It identifies the mailbox, message, and thread. Each authorized
process can then fetch the current resource it needs.

### Permissions matter

Email often contains private or regulated data. A persistent mailbox can make access a
first-class rule instead of relying on whoever received the webhook payload.

Startup Mail separates workspace roles from API resource boundaries. A workspace administrator
does not automatically gain access to a private mailbox's messages. An API key can be limited
to one tenant or mailbox, then narrowed by capabilities.

## Why a good system uses both

The most useful pattern is simple:

```text
incoming email
      ↓
persistent mailbox stores the message
      ↓
signed webhook announces the event
      ↓
your worker fetches the current thread
      ↓
policy, automation, or human review
      ↓
reply is stored in the same thread
```

The mailbox preserves state. The webhook reduces delay.

Startup Mail's `message.received` event contains identifiers for the message, mailbox, and
thread. It is a signal to fetch the current resource, not a complete replacement for the thread
response.

This design also limits what moves through event systems. A queue may need an opaque thread ID,
not a copy of every message body and attachment.

## How to handle webhooks safely

A public webhook endpoint receives requests from the internet. Do not trust a request because
it has the expected JSON fields.

### Verify the signature first

Startup Mail signs the timestamp and exact raw request body with HMAC-SHA256. Verify the
signature before parsing the JSON. Use a constant-time comparison and reject timestamps outside
your replay window.

If you parse and then reserialize the body before checking it, spacing or key order can change
and break valid signatures. More important, verification should cover the bytes that arrived.

Signature verification is a standard webhook control. GitHub gives the same core advice in its
[webhook validation guide](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries):
compute the expected signature from the secret and payload, then compare it with the supplied
value.

### Return quickly

Do not run a model, download attachments, or call several external services before
acknowledging the event.

Verify the signature, persist the delivery ID, enqueue the job, and return a `2xx` response.
Slow work can time out and cause a retry even when the first attempt is still running.

Startup Mail retries non-success responses and network failures up to five delivery attempts
with increasing delay.

### Expect duplicate delivery

At-least-once delivery means an event can arrive more than once. Store the value from
`StartupMail-Delivery` and make each side effect idempotent.

Deduplicating only the HTTP request may not be enough. The downstream operation also needs
protection. Use a stable key when creating a ticket, booking, or payment record so a crash
between the side effect and your final database update does not duplicate the action.

### Fetch current state

The thread may change after the event was created. A person may reply or another message may
arrive while your job waits in a queue.

Fetch the thread just before the important action. Check which message triggered the job and
whether a newer response makes the planned action stale.

## What you must build with a webhook-only service

A webhook-only provider can still support a complete product, but the work moves into your
application.

You may need to build:

- Raw message and attachment storage
- MIME and character-set handling
- Conversation threading
- Search and message lists
- Read, send, and private-mailbox permissions
- An inbox for human review
- Reply headers and recipient rules
- Retry, deduplication, and reconciliation jobs
- Retention and deletion controls
- Audit records for automated actions

That may be the right choice when email is a small input to a larger system and you already have
most of this infrastructure. It is a poor trade when you mainly want a reliable mailbox that
code can use.

## Questions to ask before choosing

Ask these questions in order:

1. Do we need the original message after processing?
2. Can the sender reply later?
3. Must a person be able to inspect or answer the email?
4. Will more than one service need the same thread?
5. Do we need mailbox-level privacy?
6. Can we rebuild state if one webhook is lost or processed incorrectly?
7. Are we prepared to store MIME and attachments safely?
8. Who owns threading, retention, search, and deletion?

If the first four answers are no, a webhook may be enough. If any are yes, a persistent
mailbox deserves serious consideration.

## Frequently asked questions

### Does a webhook store the email?

Not by itself. It delivers data to your endpoint. Your application must store the payload or
fetch the message from a provider that retains it.

### Is polling better than a webhook?

Polling is simpler in some low-volume systems and can help reconciliation. A webhook gives
faster notice and avoids repeated empty requests. Many reliable systems use webhooks for speed
and periodic checks for recovery.

### Should the webhook payload include the full message?

A compact event with resource IDs is often safer and easier to evolve. The consumer can fetch
the current message or thread with its own authorized key. A full payload may be useful for
stateless processing, but it spreads private content into logs, queues, and retry systems.

### Can an AI agent work from webhook payloads alone?

It can process one message, but it may miss later replies or actions taken by people. Fetch the
current thread before the agent drafts or sends a response.

### Does a persistent mailbox replace webhooks?

No. The mailbox stores state. A webhook tells your application when that state changes. Use
both when you need durable conversations and prompt processing.

The choice is not webhook or inbox in every case. Decide where the durable record lives. If
email itself matters after the first event, keep a mailbox and use the webhook to wake your
application.

## Sources

- [GitHub guide to validating webhook deliveries](https://docs.github.com/en/webhooks/using-webhooks/validating-webhook-deliveries)
- [Internet Message Format, RFC 5322](https://www.rfc-editor.org/rfc/rfc5322.html)
- [Startup Mail webhook guide](https://staging.startupmail.dev/docs/webhooks.md)
- [Startup Mail receiving guide](https://staging.startupmail.dev/docs/receiving.md)
- [How Startup Mail works](https://staging.startupmail.dev/docs/how-it-works.md)

## Related reading

- [Startup Mail vs Postmark](https://staging.startupmail.dev/compare/postmark-alternative.md): Compare Startup Mail and Postmark for transactional sending, inbound email, persistent inboxes, teams, APIs, analytics, and pricing.
- [Email API vs inbox API: What are you actually building?](https://staging.startupmail.dev/guides/email-api-vs-inbox-api.md): Learn the difference between a sending API, inbound email processing, and an inbox API, then choose the right email architecture for your product.
- [The complete guide to email for AI agents](https://staging.startupmail.dev/guides/email-for-ai-agents.md): Learn how to give an AI agent a real mailbox with scoped access, durable threads, safe sending, webhooks, MCP tools, and human review.
