Email SDK
Adapters

Postmark

Send through the Postmark Email API with message streams, metadata, and Postmark's single-tag model.

The Postmark adapter calls the Postmark Email API over fetch — no extra dependency. Its distinctive feature is message streams: set messageStream once and every send routes through that Postmark stream.

Postmark logo
Postmark
@opencoredev/email-sdk/postmark
OfficialNot API testedRequest tested
Open website

Configure

Create a server token for the server you send through, and make sure the sender signature or domain is approved in Postmark.

lib/email.ts
import { createEmailClient } from "@opencoredev/email-sdk";
import { postmark } from "@opencoredev/email-sdk/postmark";

export const email = createEmailClient({
  adapters: [
    postmark({
      serverToken: process.env.POSTMARK_SERVER_TOKEN!,
      messageStream: "outbound",
    }),
  ],
});

Prop

Type

Send

Postmark maps cc, bcc, replyTo, headers, attachments, metadata, and one tag.

const result = await email.send({
  from: "Acme <hello@acme.com>",
  to: "user@example.com",
  replyTo: "support@example.com",
  subject: "Your receipt for order ord_123",
  html: "<p>Thanks for your order.</p>",
  metadata: { orderId: "ord_123" },
  tags: [{ name: "type", value: "receipt" }],
});

console.log(result.id); // Postmark MessageID, also exposed as result.messageId

metadata becomes Postmark Metadata, and result.accepted echoes Postmark's To line.

One tag per message

Postmark has a single Tag field. The adapter serializes the first tag as name:value and a second tag throws an EmailValidationError before any request is made. Need multiple tags? Check the field support matrix.

Verify from the CLI

POSTMARK_SERVER_TOKEN="..." npx email-sdk doctor --adapter postmark
POSTMARK_SERVER_TOKEN="..." npx email-sdk send \
  --adapter postmark \
  --message-stream outbound \
  --from "Acme <hello@acme.com>" \
  --to user@example.com \
  --subject "Postmark smoke test" \
  --text "It works" \
  --dry-run

The token also accepts the --server-token flag. Drop --dry-run for one real send — that is the only check that proves the server token, sender signature, and message stream are ready.

On this page