Tutorials / Backend integrations / Send transactional email with Postmark
📝 Written ● Beginner Updated 2026-05-13

Send transactional email with Postmark

Postmark's pitch is one thing: deliverability. They actively police their senders, refuse marketing email, and run separate IPs for transactional traffic. Mail from Postmark lands in the inbox more reliably than from any general-purpose provider — at a slightly higher per-email price.

When to pick Postmark

0
  • Pick Postmark when — inbox placement is the priority. Password resets, magic links, receipts, anything where mail-in-spam is a real cost.
  • Pick Resend for cheaper per-email pricing + React Email templates.
  • Pick SendGrid for enterprise volume / sub-account hierarchies.
  • Pick AWS SES for $0.10/1K emails if you already use AWS.
  • Postmark explicitly bans marketing emails on its transactional servers. If you also need newsletters, use a separate marketing provider (Loops, Customer.io) or split your Postmark account into transactional + broadcast streams.

Sign up

1

Sign up at postmarkapp.com ↗. Free tier: 100 emails/month forever. Trial: 100 emails/month, then $15/mo for 10K.

Create a Server — Postmark's term for a project. Each server has its own API token. Common pattern: one server per environment (production, staging).

Verify your sending domain

2

Postmark won't let you send from @yourdomain.com until you verify ownership. Server → Sender Signatures → Add Domain.

Add three DNS records at your DNS provider:

  • DKIM (TXT record) — cryptographic signature proving the mail came from authorized servers.
  • Return-Path (CNAME) — where bounces go. Required for full deliverability.
  • SPF (TXT record, often pre-existing — Postmark gives you the include directive to add).

Postmark verifies automatically; usually green within 30 minutes.

Optionally add DMARC too. Postmark has a great free DMARC analyzer ↗ that emails you weekly reports.

Grab the API token

3

Server → API Tokens. Copy the Server API token:

POSTMARK_SERVER_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Different from the Account API token (which is for managing servers; not for sending). The server token is what your app uses to send mail.

Install the SDK

4
npm install postmark

Other languages: Python, Ruby, PHP, Java, Go, .NET ↗. Or just use plain HTTP — the API is a small JSON surface.

Send your first email

5
import { ServerClient } from "postmark";

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

await client.sendEmail({
  From: "[email protected]",
  To: "[email protected]",
  Subject: "Hello from Postmark",
  TextBody: "Plain text version",
  HtmlBody: "<p>HTML body</p>",
  MessageStream: "outbound",   // "outbound" = transactional; default
});

Check your recipient inbox. If it arrives, you're done. If it doesn't, the Postmark dashboard → Activity shows every send attempt with its status and the receiving server's response.

Use templates

6

For emails you send repeatedly (welcome, password reset, receipts), use Postmark Templates — they're editable in the dashboard without redeploying your app.

Server → Templates → Create template. Postmark uses Mustache ↗ syntax for variables:

<p>Hi {{name}},</p>
<p>Click here to verify: {{verifyUrl}}</p>

Send by ID or alias:

await client.sendEmailWithTemplate({
  From: "[email protected]",
  To: user.email,
  TemplateAlias: "welcome",   // or TemplateId: 12345
  TemplateModel: {
    name: user.name,
    verifyUrl: `https://yourapp.com/verify/${token}`,
  },
});

For richer template DX, the open-source MJML ↗ language compiles to email-safe HTML and works with Postmark templates. Postmark also has free pre-designed templates ↗ you can import.

Set up Message Streams (transactional vs broadcast)

7

Postmark separates transactional (one-to-one, in response to a user action) from broadcast (one-to-many, like newsletters). They use different IP pools so a bad broadcast doesn't poison your transactional reputation.

  • Outbound (default) — transactional. Password resets, receipts, magic links.
  • Broadcast — for newsletters or "important update to all users" mass mailings.

If you only do transactional, you don't need to touch this. If you also do broadcast, create a second stream and pass MessageStream: "broadcast" for those sends.

Track opens, clicks, bounces

8

Server → Settings → Tracking. Toggle:

  • Open tracking — a 1×1 pixel that fires on email open. Useful for engagement metrics; many users (and some clients) block these.
  • Click tracking — rewrites every URL through Postmark. Useful for click-through stats; can break URLs in unusual cases.

For password-reset / magic-link mail, turn click tracking off — it rewrites the URL and some email clients pre-fetch URLs, accidentally consuming single-use tokens.

Listen for bounces via webhooks

9

Server → Webhooks → Add webhook. Pick events: bounces, spam complaints, opens, clicks, delivery. Postmark POSTs your URL with event details.

Most important: handle hard bounces by suppressing the recipient. Sending to invalid addresses is the fastest way to ruin your sending reputation. The Postmark client lets you query suppressions, and the bounce webhook gives you a structured event to act on.

Webhooks docs ↗.

Common failures

10
  • "Sender signature not confirmed" — your domain isn't verified yet. Wait for DKIM/Return-Path to propagate, or retry verification.
  • "Inactive recipient" — that address bounced or marked spam previously; Postmark suppresses it. Lift suppression manually in dashboard if you're sure it's safe.
  • "Approval required" — Postmark holds account approval before lifting low limits for new accounts. They sometimes ask follow-up questions about your use case.
  • "Account locked" — Postmark detected something that looks like marketing or spam volume; they're strict. AUP ↗.
Postmark is strict about acceptable use. They review accounts manually and won't hesitate to suspend accounts sending anything that looks like marketing on the transactional stream. Their reputation depends on it. Read the AUP ↗ before signing up if you're not sure your use case fits.

Pricing reality

11

Free: 100 emails/month forever.

Paid: starts $15/mo for 10K emails. Scales linearly past that. Postmark pricing ↗.

Per-email cost is roughly 2–3× Resend's and 10× AWS SES's. You're paying for deliverability — Postmark routinely places higher in independent inbox-placement tests.

Official references

What's next