> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zavu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Email Health & Deliverability

> Understand how Zavu monitors your email bounce rate and protects your sender reputation

Zavu monitors your email deliverability to protect your sender reputation and ensure high delivery rates. This guide explains how the system works and what happens when bounce rates exceed safe thresholds.

## Why Email Health Matters

Email providers like Gmail, Yahoo, and corporate mail servers track sender reputation. A high bounce rate indicates poor list hygiene and can result in:

* Your emails being marked as spam
* Reduced inbox placement
* Complete blocking by email providers
* Amazon SES account suspension

Zavu automatically monitors and enforces bounce rate limits to protect both your reputation and our shared sending infrastructure.

## Bounce Rate Thresholds

We track your bounce rate over a rolling 7-day window:

| Bounce Rate  | Status       | Impact                                                     |
| ------------ | ------------ | ---------------------------------------------------------- |
| **\< 5%**    | Healthy      | No restrictions                                            |
| **5% - 8%**  | Warning      | You'll receive a notification to review your email list    |
| **8% - 10%** | Email Paused | Email sending is paused; SMS and WhatsApp continue working |
| **> 10%**    | Suspended    | All API access is suspended until resolved                 |

<Warning>
  Amazon SES has a strict **0.1% complaint rate** threshold. If recipients mark your emails as spam, your account may be suspended immediately.
</Warning>

## Types of Bounces

### Hard Bounces

Permanent delivery failures that immediately add the email to the suppression list:

* **Invalid address**: Email address doesn't exist
* **Domain not found**: Domain has no mail servers
* **Rejected**: Server permanently rejected the message

### Soft Bounces

Temporary delivery failures that are tracked:

* **Mailbox full**: Recipient's mailbox is full
* **Server temporarily unavailable**: Try again later
* **Message too large**: Email exceeded size limits

<Note>
  After **3 soft bounces** to the same address within 7 days, the email is automatically added to the suppression list for 7 days.
</Note>

## Email Suppression List

The suppression list prevents sending to addresses that have bounced or complained. This protects your bounce rate from known-bad addresses.

When you try to send to a suppressed email:

```json theme={null}
{
  "code": "bad_request",
  "message": "Cannot send to user@example.com: Email is suppressed (hard_bounce)"
}
```

### Suppression Reasons

| Reason        | Duration  | Description                                  |
| ------------- | --------- | -------------------------------------------- |
| `hard_bounce` | Permanent | Email address is invalid                     |
| `soft_bounce` | 7 days    | Temporary issue, will retry after expiration |
| `complaint`   | Permanent | Recipient marked email as spam               |
| `unsubscribe` | Permanent | Recipient unsubscribed                       |
| `manual`      | Permanent | Manually added by you                        |

## What Happens When You're Suspended

### Warning Level (5-8%)

* Email notification sent to account owner
* Yellow banner appears in dashboard
* No sending restrictions yet
* **Action required**: Review and clean your email list

### Email Paused Level (8-10%)

* Email sending is blocked
* SMS and WhatsApp continue working
* Orange banner appears in dashboard
* **Action required**: Remove invalid emails and contact support

### Suspended Level (>10%)

* All API access is blocked (400 errors)
* Red banner appears in dashboard
* **Action required**: Contact support immediately

## Checking Your Email Health

### Dashboard

Visit the **Email Health** page in your dashboard to see:

* Current bounce rate and status
* Suppressed email addresses
* Suspension history

### API

Check if an email is suppressed before sending:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // The API automatically checks suppression
  // You'll get an error if the email is suppressed
  try {
    await zavu.messages.send({
      to: "user@example.com",
      channel: "email",
      subject: "Hello",
      text: "Your message"
    });
  } catch (error) {
    if (error.code === "bad_request" && error.message.includes("suppressed")) {
      console.log("Email is suppressed, skipping");
    }
  }
  ```

  ```python Python theme={null}
  # The API automatically checks suppression
  # You'll get an error if the email is suppressed
  try:
      zavu.messages.send(
          to="user@example.com",
          channel="email",
          subject="Hello",
          text="Your message"
      )
  except ZavuError as e:
      if "suppressed" in str(e):
          print("Email is suppressed, skipping")
  ```

  ```ruby Ruby theme={null}
  # The API automatically checks suppression
  # You'll get an error if the email is suppressed
  begin
    client.messages.send(
      to: "user@example.com",
      channel: "email",
      subject: "Hello",
      text: "Your message"
    )
  rescue Zavudev::Error => e
    if e.message.include?("suppressed")
      puts "Email is suppressed, skipping"
    end
  end
  ```

  ```go Go theme={null}
  // The API automatically checks suppression
  // You'll get an error if the email is suppressed
  _, err := client.Messages.Send(context.TODO(), zavudev.MessageSendParams{
  	To:      zavudev.String("user@example.com"),
  	Channel: zavudev.String("email"),
  	Subject: zavudev.String("Hello"),
  	Text:    zavudev.String("Your message"),
  })
  if err != nil {
  	if strings.Contains(err.Error(), "suppressed") {
  		fmt.Println("Email is suppressed, skipping")
  	}
  }
  ```

  ```php PHP theme={null}
  // The API automatically checks suppression
  // You'll get an error if the email is suppressed
  try {
      $client->messages->send([
          'to' => 'user@example.com',
          'channel' => 'email',
          'subject' => 'Hello',
          'text' => 'Your message',
      ]);
  } catch (Zavudev\Error $e) {
      if (str_contains($e->getMessage(), 'suppressed')) {
          echo "Email is suppressed, skipping\n";
      }
  }
  ```
</CodeGroup>

## How to Maintain Good Email Health

### 1. Verify Email Addresses

Use double opt-in to ensure email addresses are valid:

```typescript theme={null}
// Step 1: User signs up
await zavu.messages.send({
  to: userEmail,
  channel: "email",
  subject: "Verify your email",
  text: `Click here to verify: ${verificationLink}`
});

// Step 2: Only add to your list after they click
```

### 2. Clean Your List Regularly

Remove emails that:

* Haven't opened emails in 6+ months
* Have bounced previously
* Have unsubscribed

### 3. Use Engagement-Based Sending

Send more frequently to engaged users, less to inactive ones.

### 4. Monitor Bounce Rates

Check your Email Health dashboard weekly. Address issues before reaching thresholds.

### 5. Handle Bounces Gracefully

```typescript theme={null}
// When a bounce webhook arrives, update your database
app.post("/webhooks/zavu", (req, res) => {
  const { type, data } = req.body;

  if (type === "message.failed" && data.errorCode === "bounce") {
    // Mark user as having invalid email
    await db.users.update({
      where: { email: data.to },
      data: { emailInvalid: true }
    });
  }
});
```

## Resolving a Suspension

If your account is suspended:

1. **Review the Email Health dashboard** to understand the cause
2. **Export and clean your email list** - remove all bounced addresses
3. **Contact support** at [support@zavu.dev](mailto:support@zavu.dev) with:
   * Your project ID
   * Steps you've taken to clean your list
   * Your plan to prevent future issues

<Info>
  Suspensions are typically resolved within 24-48 hours after you've demonstrated list cleanup.
</Info>

## Best Practices Summary

<CardGroup cols={2}>
  <Card title="Do" icon="check">
    * Use double opt-in
    * Clean lists regularly
    * Monitor bounce rates weekly
    * Handle bounces in webhooks
    * Remove unsubscribes immediately
  </Card>

  <Card title="Don't" icon="xmark">
    * Buy or rent email lists
    * Send to old, unverified lists
    * Ignore bounce notifications
    * Re-add bounced emails
    * Send without permission
  </Card>
</CardGroup>

## Related

* [Sending Emails](/guides/sending-messages/email) - How to send emails via the API
* [Webhooks](/guides/receiving-messages/webhooks) - Handle bounce and complaint events
* [Data Exports](/guides/data-exports/overview) - Export your suppression list
