Postmark
Send through the Postmark Email API with message streams, metadata, and Postmark's single-tag model.
Capabilities
| Repeated headers | Idempotency | Scheduling | Personalized |
|---|---|---|---|
| Yes | none | No | expanded |
These values come from the adapter's exported capabilities declaration. The field support matrix covers normalized message fields.
The Postmark adapter calls the Postmark Email API with plain fetch. Its distinctive feature is message streams: set messageStream once and every send routes through that Postmark stream.
Configure
Create a server token for the server you send through, and make sure the sender signature or domain is approved in Postmark.
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 MessageIDmetadata 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 --package @opencoredev/email-sdk email-sdk doctor --adapter postmarkPOSTMARK_SERVER_TOKEN="..." npx --package @opencoredev/email-sdk 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-runThe token also accepts the --server-token flag. Drop --dry-run for one real send to confirm the server token, sender signature, and message stream actually work together.
Compare Postmark with other providers
Side-by-side message-field support from the SDK capability matrix, with working code for both adapters:
Frequently asked questions
Does Email SDK support Postmark?
Yes. Email SDK ships a Postmark adapter imported from @opencoredev/email-sdk/postmark. You keep your Postmark account and credentials; the SDK adds message validation, typed errors, and no-network test adapters around the same send() call used for every other provider.
Which message fields does the Postmark adapter support?
Postmark supports CC recipients, BCC recipients, Reply-To address, Custom headers, Attachments, Tags, and Metadata. It does not support Scheduled sending (sendAt); Email SDK rejects a message that uses those fields before any request is made.
Can Postmark schedule email for later with Email SDK?
No. Postmark has no provider-side scheduling, so a message with sendAt fails validation. Store the job in your own queue and send when it is due.
Does the Postmark adapter support idempotent sends?
No. Postmark has no provider-side idempotency, so a retried send can be delivered twice. Deduplicate in your own queue before retrying.