Bounce hooks are HTTP callbacks that send your application near-real-time data when an email you sent bounces. They turn a delivery failure from a dashboard-only event into an actionable system event: your application can suppress an invalid recipient, retry a temporary failure, alert an account owner, or open an investigation automatically.
Bounce hooks, bounce webhooks, and delivery events
A bounce hook is another name for a bounce webhook. A transactional email provider sends an HTTP POST request to an endpoint you control after it identifies a bounce associated with an outbound message.
The central idea is simple: instead of repeatedly polling a provider API or relying on a human to inspect delivery logs, your application receives a push notification when the relevant event occurs. The payload generally contains enough context to connect the failure to a recipient, message, sending stream, and diagnostic response from the receiving mail system.
A bounce hook is not itself an email protocol feature. SMTP servers communicate delivery outcomes through SMTP replies and, in some cases, delivery status notifications (DSNs). The hook is the email provider's application-level way of exposing those outcomes to your software.
For example, an application sends a password-reset email to alex@example.net. The recipient domain's mail server may reject it during SMTP delivery with a response such as:
550 5.1.1 <alex@example.net>: Recipient address rejected: User unknown
Your provider records that result, classifies it as a bounce, and posts a JSON event to an endpoint such as:
POST /webhooks/email/bounce HTTP/1.1
Host: app.example.com
Content-Type: application/json
{
"event": "bounce",
"message_id": "msg_01HV...",
"recipient": "alex@example.net",
"smtp_code": 550,
"enhanced_status_code": "5.1.1",
"reason": "Recipient address rejected: User unknown",
"occurred_at": "2026-08-14T16:42:08Z"
}
The exact field names, authentication scheme, retry schedule, and event taxonomy vary by provider. Treat the example as an integration model rather than a copy-and-paste provider contract. Before coding against a particular service, use its API documentation as the source of truth; for Volanea users, the email API reference and setup guides are the appropriate place to verify the provider-specific payload and endpoint behavior.
Where a bounce hook fits in the email delivery path
To understand why bounce hooks matter, it helps to separate sending, acceptance, delivery, and feedback. These steps are related, but they are not the same event.
- Your application submits a message. It may use an HTTP REST API or authenticate to an SMTP relay.
- Your provider accepts the submission. This generally means it accepted the request for processing, not that the recipient received the message.
- The provider's sending infrastructure connects to the recipient domain's mail exchanger. It discovers the destination through DNS MX records, then negotiates SMTP delivery.
- The receiving mail server accepts, defers, or rejects the message. It can issue an immediate SMTP response, such as a
250,421,450, or550reply. - The provider records the outcome. A permanent rejection can become a bounce event immediately. A temporary rejection may be retried for a period of time before it becomes a final failure.
- The provider delivers the bounce hook. It sends an HTTPS request to your endpoint with the event details.
- Your application takes action. It updates recipient state, queues a retry, creates a support task, or sends the event to observability tooling.
A 250 response during SMTP means the receiving server accepted the message at that stage. It does not guarantee inbox placement, that the recipient read the email, or even that later processing will not result in an asynchronous non-delivery report. Conversely, an HTTP 202 Accepted returned by an email API commonly indicates that the provider accepted your request for later processing; it is not a delivery confirmation.
This distinction is important in transactional systems. If a user requests a sign-in link, an API success response tells your application that it handed off the email. A delivery event can give more confidence that a receiving server accepted it. A bounce hook tells you when delivery definitely failed or was eventually declared unsuccessful.
What counts as a bounce?
A bounce is a delivery failure reported while a message is being routed to a recipient. The word is widely used, but its operational meaning is broader than a single SMTP code.
A provider can learn about a failed message in two main ways:
Immediate SMTP rejection
The sending server attempts delivery and the recipient's server rejects the recipient or message during the SMTP conversation. The provider can classify this result right away.
A simplified exchange looks like this:
C: MAIL FROM:<bounces@bounce.example.com>
S: 250 2.1.0 OK
C: RCPT TO:<alex@example.net>
S: 550 5.1.1 User unknown
The rejection occurred at the recipient stage, before the message body was transmitted. This is usually a clear signal that the recipient address cannot currently receive mail.
Asynchronous delivery status notification
Sometimes an upstream mail server initially accepts a message and later discovers that it cannot complete delivery. It can generate a delivery status notification, often called a DSN or non-delivery report. Providers commonly control the envelope sender, also known as the MAIL FROM or return-path address, so these machine-generated reports return to infrastructure they monitor.
That return path is different from the visible From: header that the recipient sees. For example:
From: Acme Support <support@example.com>
Return-Path: <bounces+abc123@bounce.example.com>
The visible From: address is part of the message header. The return path is used for SMTP-level bounce handling. A provider can encode a message identifier in the envelope sender, receive the DSN, parse its fields, and associate the result with the original outbound message.
A bounce is not the same as every negative email event
Keep these cases separate in your data model:
- Bounce: the receiving mail system could not deliver the message, either permanently or after retries.
- Deferral: a temporary SMTP failure that the sender may retry. It is not necessarily a final bounce yet.
- Spam complaint: the recipient marked a delivered message as spam. This is a reputation and consent signal, not a technical delivery failure.
- Unsubscribe: the recipient asked not to receive a category of mail. This is a preference or compliance event.
- Dropped or suppressed send: your provider intentionally did not attempt delivery because the address was previously suppressed, malformed, unsubscribed, or blocked by policy.
- Delivered event: a receiving server accepted the message. It does not establish that the message appeared in the inbox or was viewed.
Keeping those events distinct avoids costly mistakes. For example, you should not retry a user who unsubscribed, and you should not label a temporary rate-limit response as an invalid email address.
Reading SMTP bounce codes and enhanced status codes
Bounce hooks often include both a three-digit SMTP reply code and an enhanced status code. The three-digit code describes the broad SMTP result; the enhanced code adds a standardized, machine-readable category.
SMTP reply codes use the first digit as a high-level outcome:
2xx— success or acceptance.4xx— transient negative completion: delivery may succeed later, so the sending system may retry.5xx— permanent negative completion: the current attempt should not be retried unchanged.
Enhanced status codes add more detail in the form class.subject.detail, such as 5.1.1. The first number has the same broad meaning: 4 is persistent but temporary, and 5 is permanent. The remaining numbers help identify whether the problem concerns the address, mailbox, mail system, routing, content, or security policy.
Common codes you may see in bounce hooks
| SMTP reply | Enhanced code | Typical interpretation | Usual application action |
|---|---|---|---|
421 | 4.3.2 or similar | Service unavailable or temporarily unable to process mail | Let the provider retry; investigate if persistent |
450 | 4.2.0 | Mailbox temporarily unavailable | Do not immediately suppress; retry later |
451 | 4.3.0 | Local processing error or temporary server problem | Retry and monitor trends |
452 | 4.2.2 | Insufficient storage or temporary quota condition | Retry; do not assume the address is invalid |
550 | 5.1.1 | Recipient mailbox does not exist | Suppress the address for the affected mail type, usually immediately |
550 | 5.7.1 | Delivery rejected because of policy, authentication, reputation, or content | Investigate sender configuration and content; do not blame the recipient automatically |
552 | 5.2.2 | Mailbox storage limit exceeded | Treat carefully; provider classification and recurrence matter |
553 | 5.1.3 | Invalid mailbox syntax or address format | Correct or suppress the address |
554 | 5.7.1 or another 5.x.x | Transaction failed, often due to policy or message-level rejection | Inspect the diagnostic text and sending configuration |
The table is a practical starting point, not an exhaustive rule engine. Mailbox providers and corporate gateways can use proprietary diagnostic text, and some responses that look permanent are caused by a temporary reputation, authentication, or routing condition.
The most useful fields are usually the combination of the SMTP code, enhanced code, diagnostic text, recipient domain, and timing. For instance, a single 550 5.1.1 for one address strongly suggests an invalid mailbox. Hundreds of 550 5.7.1 failures across one domain after a DNS change suggest a sender-side configuration issue.
Hard bounces and soft bounces are useful but not universal standards
Email platforms often label bounce categories as hard and soft:
- A hard bounce generally means a permanent failure, such as an unknown recipient, invalid domain, or invalid mailbox syntax.
- A soft bounce generally means a temporary failure, such as a full mailbox, temporary outage, connection issue, or rate limit.
These labels are operational shortcuts, not strict protocol terms. Providers may classify the same SMTP response differently based on their own retry history, recipient-domain behavior, and deliverability policy. Your application should preserve the raw response and provider category rather than relying only on a boolean field named hard_bounce.
What a robust bounce-hook payload should contain
Providers expose different schemas, but your internal event model should capture the information needed for safe automation and later debugging.
At a minimum, retain:
- Provider event ID: a unique event identifier used for idempotency and support investigations.
- Original message ID: your provider message identifier and, when available, your own correlation ID.
- Recipient address: normalize safely for matching, but retain the original form for audit records where appropriate.
- Event type and classification: bounce, transient failure, suppression, policy rejection, or another provider-defined category.
- SMTP reply code: such as
550or451. - Enhanced status code: such as
5.1.1or4.7.0, when supplied. - Diagnostic text: the receiving system's human-readable explanation.
- Timestamp: when the provider observed the event, preferably in UTC.
- Envelope sender or sending domain: useful for diagnosing configuration and stream-specific problems.
- Metadata: a tenant ID, user ID, notification type, campaign ID, or internal message key that you attached at send time.
Avoid storing sensitive content in webhook payloads unless you need it. A subject line can reveal account activity, a medical topic, an invoice number, or a password-reset workflow. Store a stable internal reference instead of copying full message bodies or personal data into every bounce-processing system.
A good sending design attaches metadata when the message is submitted. For example, an account-notification service might associate tenant_id, user_id, notification_type, and notification_id with each send. When the bounce hook arrives, the handler can update the correct customer record without trying to infer ownership from the email address alone.
How to process bounce hooks safely
A webhook endpoint is an internet-facing integration. Treat it as a production message-ingestion system, not as a small controller that makes a few database updates inline.
Verify that the request is authentic
Do not assume any JSON request to /webhooks/bounce came from your email provider. Verify webhook authenticity using the exact mechanism your provider documents. Common patterns include a signature header calculated from the raw request body and a shared secret, a timestamp plus signature to reduce replay risk, or an allowlist of provider IP ranges.
Signature verification must usually use the raw, unmodified body. Parsing JSON and serializing it again can change whitespace, key order, or character encoding and cause a valid signature check to fail. Use constant-time comparison functions when comparing secret-derived signatures.
If a provider supports signed webhooks, use them. IP allowlists can be a useful defense in depth, but IP addresses may change and should not be your only control unless the provider explicitly recommends that model.
Acknowledge quickly, process asynchronously
Your endpoint should validate the request, persist or queue the event, and return a successful HTTP response quickly. Do not wait for slow database queries, third-party CRM calls, or notification workflows before acknowledging the hook.
A typical architecture is:
- Receive the HTTPS request.
- Validate its signature and basic schema.
- Store the raw event or publish it to a durable queue.
- Return
200 OKor another success response required by the provider. - Process suppression, retries, analytics, and alerts in a worker.
This design is resilient to traffic spikes and provider retry behavior. It also helps prevent a transient outage in your customer database from causing an avalanche of duplicate webhook deliveries.
Design for duplicate delivery
Webhook systems commonly retry when they do not receive a successful response. Network failures can also occur after your server processes the request but before the provider sees your response. As a result, assume a bounce event may arrive more than once.
Make handling idempotent. The simplest approach is to store the provider event ID with a unique database constraint. If the same ID arrives again, acknowledge it without performing suppression or side effects twice.
If the provider does not supply a durable event ID, derive a carefully scoped idempotency key from stable values such as the provider message ID, recipient, event type, and observed timestamp. Do not use only the recipient address: one person can legitimately receive more than one message, and each failure may be relevant.
Keep event history separate from recipient state
A recipient's current state and its historical delivery record are different data sets. Keep both.
For example, an email_events table can retain every provider event, while a recipient_delivery_state table records whether a particular address is currently suppressed for password resets, product notifications, or marketing messages. This gives support teams context without forcing your application to repeatedly parse old raw events.
A simplified recipient state might look like:
recipient: alex@example.net
status: suppressed
reason: hard_bounce
last_smtp_code: 550
last_enhanced_code: 5.1.1
last_event_at: 2026-08-14T16:42:08Z
source_message_id: msg_01HV...
Be deliberate about scope. A permanent hard bounce may justify suppressing all nonessential email. A temporary authentication failure at a recipient domain should not mark every individual address at that domain as invalid.
Choosing the right action after a bounce
The value of bounce hooks is not merely collecting telemetry. It is making the right automated decision for the failure type.
Suppress clearly invalid recipients
For a likely nonexistent mailbox, such as 550 5.1.1, stop sending to that address until the owner updates it or confirms a replacement. Continuing to send to known-invalid recipients wastes capacity and can harm sender reputation.
In account-based applications, do not silently delete an email address solely because it bounced. Mark it as undeliverable, prevent repeated sends, and present an appropriate in-product prompt the next time the user signs in. If the message was security-critical, use an alternative verified communication path where your product and policies permit it.
Before adding newly collected addresses to important workflows, an email address verification tool can help catch formatting, domain, and mail-exchange problems early. Verification reduces avoidable failures, but it cannot guarantee that every inbox will accept every future message.
Let temporary failures follow the provider's retry logic
Do not build a second retry loop that blindly resends a message whenever you receive a transient-bounce hook. Transactional providers already typically retry temporary SMTP failures according to their delivery policies. Resubmitting the same email yourself can create duplicate password-reset links, repeated receipts, or excess mail volume.
Instead, distinguish between a provider delivery retry and a business retry. Let the provider attempt SMTP redelivery for a transient mail-system condition. Only create a new application-level message when the business case truly requires it and you can do so safely.
For a time-sensitive message such as a one-time login code, a delayed email may be less useful than an alternative sign-in option. For an invoice notification, a later resend may be appropriate, but it should use a new, explicit workflow rather than a reflexive response to every 4xx event.
Investigate policy, authentication, and reputation failures
A 5.7.1 response often signals that the receiving system rejected the message for policy, security, or authorization reasons. It does not prove that the recipient address is bad.
Start by grouping events by recipient domain, sending domain, IP pool if available, and error family. Look for patterns:
- A sharp rise across many recipients at one mailbox provider may point to authentication, reputation, traffic, or provider-specific policy issues.
- A rise limited to a newly configured sending domain can indicate a DNS or alignment problem.
- Failures after a template change may indicate content, links, or formatting that triggers filtering.
- Failures associated with one tenant or message stream may reveal compromised credentials, poor recipient acquisition, or unexpected mail volume.
Use tools such as MXToolbox to inspect public DNS and mail-exchange records, and use mail-tester.com for a controlled content and authentication check. These tools are diagnostic aids, not final verdicts: the actual SMTP response, message headers, authentication results, and domain-level pattern should guide the incident response.
DNS and authentication issues that bounce hooks can reveal
Bounce hooks are downstream observability, but they often expose mistakes in DNS and sender authentication. Modern recipient systems evaluate whether the sender is authorized, identifiable, and consistent.
SPF
SPF is published as a DNS TXT record and lists hosts permitted to send mail for a domain. A syntactically valid illustrative record is:
example.com. IN TXT "v=spf1 ip4:192.0.2.0/24 -all"
192.0.2.0/24 is documentation-only address space, so do not deploy that exact record. In production, use the IP addresses or provider include mechanism documented by your actual sender. A provider-based version commonly resembles this structure:
example.com. IN TXT "v=spf1 include:provider-authorized-senders.example -all"
The include domain must be the real domain supplied by the email provider; do not guess it. SPF has a limit on DNS-mechanism lookups, so adding multiple services without planning can create failures.
DKIM
DKIM signs parts of an email message cryptographically. The public key is published under a selector-specific DNS name. Its general DNS shape is:
selector1._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=BASE64_PUBLIC_KEY"
selector1 is chosen by the sending system. The p= value must contain the full public key supplied by your sender, often split into quoted chunks by DNS tools because of record-length handling. Do not invent or truncate a live key.
DMARC
DMARC lets a domain owner publish a policy and request aggregate reporting. A basic record can be:
_dmarc.example.com. IN TXT "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com; adkim=s; aspf=s"
This example requests reports and uses strict alignment for DKIM and SPF identifiers. p=none is monitoring mode; it does not instruct receivers to quarantine or reject mail. DMARC policy changes should be made carefully after reviewing reports and confirming that all legitimate senders align correctly.
Google's sender guidance requires all senders to use SPF or DKIM, while bulk senders must use SPF, DKIM, and DMARC. Google defines bulk senders around sending roughly 5,000 or more messages per day to personal Gmail accounts, and also calls for valid forward and reverse DNS for sending domains or IPs. These requirements make bounce-hook monitoring useful: policy and authentication failures should be detected quickly rather than discovered after a customer reports a missing message.
MX and return-path checks
An MX record indicates where a domain receives email. Its format is:
example.com. IN MX 10 mail.example.com.
The target must resolve to an address record. A malformed recipient domain, missing MX setup, or unreachable destination can contribute to delivery failures. However, a domain can sometimes accept mail through fallback behavior even without an MX record, so do not reduce address validation to one DNS lookup.
Your own return-path domain also deserves attention. If your provider uses a custom bounce domain, configure the DNS records it specifies exactly, including any CNAME, MX, or TXT records. Those records are provider-specific. The right approach is to copy the documented hostnames and values, publish them at your DNS provider, and verify propagation rather than extrapolating from another platform's configuration.
Monitoring bounce hooks for deliverability signals
A single bounce is a recipient-level event. A trend is an operational signal.
Build reporting around rates and cohorts, not just total counts. A useful bounce dashboard or metrics pipeline can group events by:
- sending domain and envelope domain;
- recipient domain, such as Gmail, Outlook, or a customer's corporate domain;
- message type, such as password reset, receipt, invite, or product alert;
- application tenant, workspace, or customer account;
- provider classification and raw SMTP/enhanced status code;
- template version, deployment version, and time window.
For transactional mail, segmenting by message type is especially important. A rising hard-bounce rate on account invitations may indicate stale imported contacts. A spike in policy rejections only for password resets may indicate an unexpected template or link change. A sudden failure pattern on all categories may be more likely to involve infrastructure or domain authentication.
Set alerts for abrupt changes rather than relying on one universal bounce-rate threshold. Different mail types have different baseline behavior. A user-entered contact form may naturally produce more invalid addresses than a verified account-notification list. The important question is whether the rate is materially different from that workflow's normal level.
When an alert fires, work from the raw evidence outward:
- Confirm whether the events are immediate rejections, delayed bounces, suppressions, or webhook delivery failures.
- Group by recipient domain and error code.
- Check recent DNS, sender-domain, template, link, and volume changes.
- Inspect message headers and authentication results from controlled test sends.
- Pause or narrow risky traffic if the failure affects a broad recipient group.
- Record the diagnosis and update your bounce-classification rules if necessary.
Common implementation mistakes
Bounce hooks are straightforward conceptually, but several shortcuts create incorrect recipient records or missed failures.
Treating every 5xx response as a bad address
A 550 5.1.1 is very different from a 550 5.7.1. The first often means the mailbox does not exist; the second may mean your message failed a policy check. Suppressing the recipient after every 5xx can hide a sender-authentication incident and unnecessarily prevent legitimate users from receiving mail.
Retrying from the application without understanding provider retries
If a provider is already retrying a temporary delivery failure, sending another copy from your app can create duplicates. Check whether the event indicates a final bounce, a transient attempt, a deferral, or a completed provider retry cycle before creating another message.
Returning an error because downstream work is slow
If your webhook handler waits for a slow CRM API and times out, the provider may retry the same event. Return success after you durably queue the event, then process it asynchronously.
Ignoring signature verification
An unauthenticated webhook endpoint can be abused to suppress valid customers, trigger support tickets, or poison deliverability analytics. Verify requests using the provider's documented method and log failures without exposing secrets.
Losing raw diagnostic data
A simplified label such as hard_bounce is useful for automation, but it is not enough for incident response. Retain the raw SMTP code, enhanced code, diagnostic text, and provider event ID with appropriate privacy controls.
Assuming a bounce hook is the entire delivery system
A bounce hook is one feedback channel. Pair it with sending logs, delivery events, complaint and unsubscribe events where relevant, authentication monitoring, and product-level observability. A reliable email program needs the full lifecycle, from submission through recipient feedback.
A practical bounce-hook implementation checklist
Before enabling automated suppression or retries, verify the following:
- Create a dedicated HTTPS endpoint for bounce events.
- Verify provider signatures using the raw request body and documented secret or public-key process.
- Require TLS and restrict access through normal application security controls.
- Persist a unique provider event ID for idempotent processing.
- Return the provider-required success status promptly after durable ingestion.
- Queue heavy work such as CRM updates, analytics, and support notifications.
- Store the raw SMTP response, enhanced status code, provider category, timestamp, and message correlation ID.
- Define separate rules for invalid recipients, temporary failures, policy rejections, complaints, and unsubscribes.
- Avoid automatic application-level resend loops unless the workflow is explicitly designed for them.
- Alert on meaningful changes by recipient domain, template, sender domain, and message type.
- Test with safe provider-supported test addresses or sandbox facilities where available.
- Document a human escalation path for widespread authentication, reputation, or provider-domain incidents.
The goal is not to eliminate every bounce. Some users will mistype an address, abandon an inbox, or work at an organization that changes its mail system. The goal is to stop sending repeatedly to clearly undeliverable destinations, preserve evidence for diagnosis, and avoid confusing a recipient problem with a sender-infrastructure problem.
Conclusion
Bounce hooks connect the email delivery layer to your application. They notify your system when an outgoing message fails, carrying the technical evidence needed to distinguish an invalid mailbox from a temporary outage or sender-policy rejection.
The best implementations are secure, idempotent, and event-driven. Verify incoming requests, acknowledge them quickly, preserve raw diagnostics, and make recipient-state decisions based on the SMTP response and broader pattern rather than a simplistic hard-or-soft label. Used well, bounce hooks protect deliverability, improve customer communication, and make email failures visible while there is still time to act.
FAQ
Are bounce hooks and webhooks the same thing?
A bounce hook is a bounce-specific webhook. It is an HTTP callback from an email provider to your application when the provider detects a delivery failure for an outbound message.
Do bounce hooks fire immediately?
Often, but not always. An immediate SMTP rejection can be reported quickly. Temporary failures may be retried first, and asynchronous delivery status notifications can arrive later, so a final bounce may occur minutes or longer after the original send.
Should I suppress every bounced email address?
No. Suppress addresses that are clearly invalid, such as a likely 5.1.1 unknown-recipient result. Investigate policy, authentication, reputation, and temporary failures before marking a recipient as invalid.
Why did an email bounce after my API request succeeded?
An API success response usually means the email provider accepted your submission for processing. The recipient's mail server may reject the message later, or a temporary failure may become a final delivery failure after retries.
Can I use bounce hooks with both SMTP and REST email sending?
Yes. Whether your application submits mail through an SMTP relay or a REST API, the provider can associate later delivery outcomes with the submitted message and send bounce events to your webhook endpoint.