---
title: "Postmark"
description: "Postmark as a planned MainSDK email driver - sender domain, server token, main.yaml, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/postmark"
updated: "2026-10-28"
---

# Postmark

> Postmark as a planned MainSDK email driver - sender domain, server token, main.yaml, testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/postmark · Updated: 2026-10-28

Postmark is a hosted email delivery service focused on transactional mail. It is named as an [`email`](https://mainsdk.dev/docs/interfaces/email) driver in the MainSDK requirements, so `email.send()` and `email.marketing()` could deliver through it. Pick it if your team already sends through Postmark.

## Interfaces it serves

### Email (`email`)

- Status: Building for 0.3 · ships as a stable API
- Driver: `postmark` (Postmark, planned driver)
- Docs: https://mainsdk.dev/docs/interfaces/email.md

```yaml
email:
  driver: postmark
```

Swap to another provider: `resend`, `ses`, `local`, `bird`, `smtp`.

### Inbound mail and mailboxes (`mail`)

- Status: Building for 1.2 · ships as a experimental API
- Driver: `postmark` (Postmark inbound)
- Docs: https://mainsdk.dev/docs/interfaces/mail.md

```yaml
mail:
  driver: postmark
```

Swap to another provider: `ses`, `mailgun`, `cloudflare`, `imap`, `jmap`, `local`.

## Before you start

1. Create a Postmark server for this app and copy its server API token.
2. Add your sending domain and the DNS records Postmark gives you (DKIM and a return-path record).
3. Postmark separates transactional and broadcast mail into message streams; marketing email belongs on a broadcast stream.

Store the token in your secrets manager.

## Configure

```yaml title="main.yaml"
email:
  driver: postmark                 # planned driver, not in the spec yet
  key: secret:POSTMARK_SERVER_TOKEN   # suggested name
```

A literal key fails to load with `MAIN-CONFIG-0004`.

## Use it

```ts title="app/orders/receipt.ts"
import { email } from "mainsdk";

await email.send({ to: user.email, template: "receipt", data: { orderId: order.id } });
```

## Local development and testing

`mainsdk dev` sends every email to the local inbox. `createTestApp()` from `@mainsdk/testing` runs `email` on its in-memory fake, and `chaos.on("email", { outage: true })` simulates an outage.

## What MainSDK adds on top

- Marketing email does not compile without an unsubscribe.
- Unsubscribes, bounces and complaints suppressed for every later send.
- No tracking pixels or rewritten links by default; a retry never sends twice.

See [Email](https://mainsdk.dev/docs/interfaces/email).

## Limits and notes

- Planned driver, not in the spec yet. The email-notify spec ships Resend, Amazon SES and the local inbox; Postmark comes through the driver kit later.
- How marketing sends map to a Postmark message stream is [TBD].

## Swap to or from it

```yaml title="main.yaml"
email:
  driver: resend   # was postmark
```

Email is stateless, so the swap needs no migration; verify your domain with the new provider first.

## FAQ

**Can I use Postmark today?** Not through MainSDK yet. Use Resend or Amazon SES.

## Next

- [Email](https://mainsdk.dev/docs/interfaces/email)
- [Resend](https://mainsdk.dev/docs/integrations/resend), [Amazon SES](https://mainsdk.dev/docs/integrations/amazon-ses) and [SMTP](https://mainsdk.dev/docs/integrations/smtp)
