Postmark Integration for Transactional Email
Postmark specializes exclusively in transactional email (not bulk) and guarantees delivery in 10 seconds. They use separate IP pools for transactional and bulk emails, preserving domain reputation. A good choice if delivery speed is critical — payment confirmations, password resets.
Installation
npm install postmark
Sending via API
import * as postmark from 'postmark';
const client = new postmark.ServerClient(process.env.POSTMARK_SERVER_TOKEN!);
// Simple HTML send
await client.sendEmail({
From: '[email protected]',
To: '[email protected]',
Subject: 'Your order is confirmed',
HtmlBody: '<strong>Order #12345 accepted!</strong>',
TextBody: 'Order #12345 accepted!',
MessageStream: 'outbound', // transactional stream
});
Postmark Templates
Postmark stores templates server-side with Mustache syntax:
// Send using template (TemplateAlias from Postmark dashboard)
await client.sendEmailWithTemplate({
From: '[email protected]',
To: user.email,
TemplateAlias: 'order-confirmation',
TemplateModel: {
customer_name: user.name,
order_id: order.id,
order_total: formatCurrency(order.total),
order_url: `https://app.example.com/orders/${order.id}`,
support_email: '[email protected]',
},
MessageStream: 'outbound',
});
Webhooks for Delivery Events
// POST /api/webhooks/postmark
app.post('/api/webhooks/postmark', async (req, res) => {
const event = req.body as postmark.DeliveryWebhook | postmark.BounceWebhook;
if ('DeliveredAt' in event) {
// Delivery event
await logEmailDelivered(event.MessageID, event.Recipient);
} else if ('Type' in event) {
// Bounce event
if (event.Type === 'HardBounce') {
await markEmailInvalid(event.Email);
}
}
res.status(200).end();
});
Message Streams
Postmark separates streams:
-
outbound— transactional emails (order confirmation, reset password, invoice) -
broadcast— marketing campaigns (must be created in dashboard)
This ensures that bulk distribution doesn't harm the reputation of transactional emails.
Timeline
Postmark integration + templates + webhooks — 1–2 days.







