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

# Migrate from Resend

> Switch from Resend to the Paubox Email API for HIPAA-compliant transactional email.

## Why migrate

Resend does not sign Business Associate Agreements (BAAs). HIPAA requires a signed BAA with any vendor that handles Protected Health Information (PHI) in transit — including transactional email providers. Paubox is purpose-built for HIPAA-compliant email and signs a BAA with every customer, and TLS is always-on for every message. Resend's API uses familiar Bearer-auth and JSON patterns, so the switch is a small refactor for developers already comfortable with Resend.

## What stays the same

* REST API over HTTPS with JSON request bodies
* API key authentication via the `Authorization: Bearer` header
* Domain authentication: SPF and DKIM records required
* SMTP as an alternative to the HTTP API
* Webhook-based event notifications for delivery status

## Key differences

| Dimension          | Resend                                                                                                             | Paubox Email API                                             |
| :----------------- | :----------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------- |
| Base URL           | `https://api.resend.com/emails`                                                                                    | `https://api.paubox.net/v1/$PAUBOX_ENDPOINT/messages`        |
| Auth header        | `Authorization: Bearer $RESEND_API_KEY`                                                                            | `Authorization: Bearer $PAUBOX_API_KEY`                      |
| Request body shape | `from`, `to`, `subject`, `html` flat keys                                                                          | `data.message` object with `headers` and `content` keys      |
| Recipients field   | `to` — array of strings                                                                                            | `recipients` — array of strings, nested under `data.message` |
| SMTP host          | `smtp.resend.com`                                                                                                  | `smtp.paubox.com`                                            |
| SMTP username      | `resend` (literal)                                                                                                 | `apikey` (literal)                                           |
| SMTP port          | 465 (recommended), 587, 25                                                                                         | 587 (also supports 465, 25)                                  |
| Webhook events     | email.sent, email.delivered, email.bounced, email.opened, email.clicked, email.complained, email.delivery\_delayed | delivered, opened, temporary\_failure, permanent\_failure    |
| Batch send         | `/emails/batch` endpoint                                                                                           | `/bulk_messages` endpoint, recommended max 50 per request    |
| TLS enforcement    | Optional                                                                                                           | Always-on, cannot be disabled                                |
| BAA available      | No                                                                                                                 | Yes — signed with every customer                             |

## Send a single email

<CodeGroup>
  ```bash Resend (before) theme={null}
  curl -X POST https://api.resend.com/emails \
    -H "Authorization: Bearer $RESEND_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "from": "provider@yourclinic.com",
      "to": ["patient@example.com"],
      "subject": "Your appointment summary",
      "html": "<p>See attached.</p>"
    }'
  ```

  ```bash Paubox (after) theme={null}
  curl -X POST https://api.paubox.net/v1/$PAUBOX_ENDPOINT/messages \
    -H "Authorization: Bearer $PAUBOX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "data": {
        "message": {
          "recipients": ["patient@example.com"],
          "headers": {
            "subject": "Your appointment summary",
            "from": "provider@yourclinic.com"
          },
          "content": {
            "text/html": "<p>See attached.</p>"
          }
        }
      }
    }'
  ```
</CodeGroup>

<Note>
  **Note:**

  `$PAUBOX_ENDPOINT` is the username shown on your [Paubox Email API > Settings](https://next.paubox.com/emailapi/settings) page — not your email address.
</Note>

## SMTP configuration

<CodeGroup>
  ```js Resend (before) theme={null}
  const transporter = nodemailer.createTransport({
    host: 'smtp.resend.com',
    port: 465,
    auth: {
      user: 'resend',
      pass: process.env.RESEND_API_KEY,
    },
  });
  ```

  ```js Paubox (after) theme={null}
  const transporter = nodemailer.createTransport({
    host: 'smtp.paubox.com',
    port: 587,
    auth: {
      user: 'apikey',
      pass: process.env.PAUBOX_API_KEY,
    },
  });
  ```
</CodeGroup>

<Tip>
  **Tip:**

  Two changes are required: update `host` from `smtp.resend.com` to `smtp.paubox.com`, and change the literal username from `resend` to `apikey`.
</Tip>

## Webhook event mapping

| Resend event             | Paubox event key                 | Notes                                                                                          |
| :----------------------- | :------------------------------- | :--------------------------------------------------------------------------------------------- |
| `email.delivered`        | `api_mail_log_delivered`         |                                                                                                |
| `email.opened`           | `api_mail_log_opened`            |                                                                                                |
| `email.bounced`          | `api_mail_log_permanent_failure` |                                                                                                |
| `email.delivery_delayed` | `api_mail_log_temporary_failure` |                                                                                                |
| `email.clicked`          | — no equivalent                  | Remove handler or no-op; poll click data via [Get message receipt](/email-api/message-receipt) |
| `email.complained`       | — no equivalent                  | Remove handler                                                                                 |
| `email.sent`             | — no equivalent                  | Remove handler; `delivered` confirms acceptance                                                |

<Note>
  **Note:**

  Click tracking is available by polling `GET /message_receipt?sourceTrackingId=...` — it is not delivered as a push webhook event.
</Note>

## Migration checklist

<Steps>
  <Step title="Sign a BAA with Paubox">
    Required before go-live. Contact Paubox to initiate the Business Associate Agreement.
  </Step>

  <Step title="Create an account and verify your sending domain">
    Add your domain on the [Paubox Email API > Settings](https://next.paubox.com/emailapi/settings) page and complete the TXT record verification. See the [Quickstart guide](/email-api/quickstart) for step-by-step instructions.
  </Step>

  <Step title="Generate a Paubox API key">
    From the Settings page, generate an API key and note your customer endpoint (`https://api.paubox.net/v1/YOUR_USERNAME`).
  </Step>

  <Step title="Update base URL, auth header, and request body">
    Apply the changes shown in the [Key differences](#key-differences) table and [Send a single email](#send-a-single-email) section above. Note that recipients move from a top-level `to` array into `data.message.recipients`.
  </Step>

  <Step title="Update SMTP credentials">
    If you use the SMTP path, update `host` to `smtp.paubox.com` and change the literal username from `resend` to `apikey`. See [SMTP configuration](#smtp-configuration) above.
  </Step>

  <Step title="Remap or remove webhook handlers">
    Update your webhook endpoint using the [event mapping table](#webhook-event-mapping) above. Remove handlers for `email.clicked`, `email.complained`, and `email.sent`.
  </Step>

  <Step title="Remove any code that disables TLS">
    Paubox enforces TLS on every message. Any `allowNonTLS: true` or equivalent settings should be removed.
  </Step>

  <Step title="Send a test message">
    Confirm delivery using the [Get message receipt](/email-api/message-receipt) endpoint with the `sourceTrackingId` returned from your test send.
  </Step>

  <Step title="Swap DNS records">
    Replace Resend SPF/DKIM records with the Paubox records shown in your Settings page.
  </Step>

  <Step title="Revoke Resend API keys">
    Once traffic has fully moved to Paubox, revoke your Resend API keys.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart guide" icon="rocket" href="/email-api/quickstart">
    Full setup walkthrough from account creation to first send
  </Card>

  <Card title="Webhooks reference" icon="webhook" href="/email-api/webhooks">
    Configure delivery event notifications
  </Card>

  <Card title="Batch send" icon="layer-group" href="/email-api/bulk-messages">
    Send up to 50 messages in a single request
  </Card>

  <Card title="SMTP API" icon="server" href="/email-api/smtp">
    Connect via SMTP instead of REST
  </Card>
</CardGroup>
