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

# Migrating from Postmark

> How to translate Postmark message streams, server API tokens, and templates to Mailofly's unified architecture.

# Migrating from Postmark to Mailofly

Postmark is known for strong transactional deliverability, but developers often face limitations with strict stream separation (where mixing promotional content in transactional streams risks account suspension), premium pricing tiers, and lack of integrated AI tooling.

Mailofly delivers identical sub-second deliverability with lower costs, native AI Model Context Protocol (MCP) support, and unified multi-identity routing.

***

## Core Concept Translation

Postmark uses a unique conceptual model centered on "Servers" and "Message Streams". Here is how those concepts map to Mailofly:

| Postmark Concept         | Mailofly Concept                       | Explanation                                               |
| :----------------------- | :------------------------------------- | :-------------------------------------------------------- |
| **Server API Token**     | **API Key** (`mf_live_...`)            | Unified secret key used to authenticate all API requests. |
| **Transactional Stream** | **Transactional Send** (`emails.send`) | Standard API email dispatch with priority routing.        |
| **Broadcast Stream**     | **Broadcasts / Campaigns**             | Rich visual campaign editor and bulk sending engine.      |
| **Inbound Stream**       | **Receiving Webhook**                  | Inbound email parsing, forwarding, and webhook dispatch.  |
| **Server**               | **Sending Identity** (`account_key`)   | Isolate different apps, brands, or environments cleanly.  |

***

## 1. SDK & Code Migration

Notice that Postmark uses **PascalCase** property keys (`From`, `To`, `HtmlBody`), whereas Mailofly uses standard modern conventions (`from`, `to`, `html`).

### Node.js / TypeScript

```bash theme={null}
# Remove Postmark
npm uninstall postmark

# Install Mailofly
npm install @mailofly/node
```

<CodeGroup>
  ```ts Before: Postmark (postmark) theme={null}
  import * as postmark from "postmark";

  const client = new postmark.ServerClient(process.env.POSTMARK_SERVER_TOKEN!);

  const response = await client.sendEmail({
    From: "support@acme.com",
    To: "customer@example.com",
    Subject: "Your Password Reset Link",
    HtmlBody: "<p>Click here to reset your password.</p>",
    TextBody: "Click here to reset your password.",
    MessageStream: "outbound",
    Tag: "password-reset",
  });

  console.log("Postmark ID:", response.MessageID);
  ```

  ```ts After: Mailofly (@mailofly/node) theme={null}
  import { Mailofly } from "@mailofly/node";

  const mailofly = new Mailofly({
    apiKey: process.env.MAILOFLY_API_KEY!,
  });

  const { id } = await mailofly.emails.send({
    from: "Acme Support <support@acme.com>",
    to: ["customer@example.com"],
    subject: "Your Password Reset Link",
    html: "<p>Click here to reset your password.</p>",
    text: "Click here to reset your password.",
    tags: [{ name: "type", value: "password-reset" }],
  });

  console.log("Mailofly ID:", id);
  ```
</CodeGroup>

***

### Python

<CodeGroup>
  ```python Before: Postmark (postmarker) theme={null}
  from postmarker.core import PostmarkClient

  postmark = PostmarkClient(server_token="POSTMARK_SERVER_TOKEN")

  response = postmark.emails.send(
      From="support@acme.com",
      To="customer@example.com",
      Subject="Your invoice",
      HtmlBody="<p>Invoice attached.</p>",
  )
  ```

  ```python After: Mailofly theme={null}
  from mailofly import Mailofly
  import os

  client = Mailofly(api_key=os.environ["MAILOFLY_API_KEY"])

  response = client.emails.send(
      sender="Acme Support <support@acme.com>",
      to=["customer@example.com"],
      subject="Your invoice",
      html="<p>Invoice attached.</p>",
  )
  ```
</CodeGroup>

***

## 2. Inbound Email Processing

If you use Postmark Inbound Webhooks to process emails sent to your domain, switching to Mailofly's Inbound Engine is straightforward:

1. **Configure Custom Inbound Domain**: In Mailofly, go to **[Receiving](https://www.mailofly.com/user/receiving)** and register your inbound domain (e.g., `inbound.example.com`).
2. **Add MX Records**: Set your MX record to point to Mailofly's inbound mail server:
   ```dns theme={null}
   inbound.example.com  MX  10  inbound.mailofly.com
   ```
3. **Webhook Payload Comparison**:

| Postmark Inbound Field | Mailofly Inbound Field | Description                                    |
| :--------------------- | :--------------------- | :--------------------------------------------- |
| `From` / `FromName`    | `from`                 | Sender address and display name                |
| `To`                   | `to`                   | Recipient address                              |
| `Subject`              | `subject`              | Email subject                                  |
| `HtmlBody`             | `html`                 | HTML body content                              |
| `TextBody`             | `text`                 | Raw plaintext message                          |
| `Attachments`          | `attachments`          | Array of attachment metadata and download URLs |
| `Headers`              | `headers`              | Full parsed MIME headers                       |

***

## 3. Suppressions & Blacklist Migration

Postmark automatically suppresses hard bounces, spam complaints, and manual unsubscribes:

1. In the Postmark dashboard, navigate to your server → **Suppressions**.
2. Click **Export** to download your suppressed recipient list as a CSV.
3. In Mailofly, go to **[Audiences > Contacts](https://www.mailofly.com/user/audience)** and click **Import Contacts**.
4. Upload your CSV and select **Mark as Suppressed** to prevent sending to any previously invalid addresses.

***

## Migration Checklist

* [ ] Add domain in Mailofly and add `mailofly._domainkey` DKIM record.
* [ ] Add `include:mailofly.com` to your domain's SPF record alongside Postmark.
* [ ] Update client code from PascalCase (`From`, `HtmlBody`) to lowerCamelCase (`from`, `html`).
* [ ] Export Postmark Suppressions and import them into Mailofly.
* [ ] Update Inbound MX records and webhook destinations (if receiving inbound email).
* [ ] Send verification test emails and confirm delivery on the Mailofly dashboard.


## Related topics

- [Migrating from Resend](/guides/migrations/resend.md)
- [Migrating from Mailgun](/guides/migrations/mailgun.md)
- [Migrating from Amazon SES](/guides/migrations/aws-ses.md)
- [Migrating from Mailchimp & Mandrill](/guides/migrations/mailchimp.md)
- [Migrating from Twilio SendGrid](/guides/migrations/sendgrid.md)
