Postmark API guide: fast transactional email, explained
How the Postmark API works: server tokens, the /email endpoint, message streams, templates, inbound processing - and when Postmark is or isn't the right choice.
Dvir Atias
Founder
Postmark built its reputation on one promise: transactional email that arrives fast, with deliverability treated as the product. The API reflects that focus - small, clean, JSON-first. This guide covers the pieces you'll use: authentication, sending, message streams, templates, and inbound - plus an honest look at where Postmark's sharp focus becomes a limitation.
Authentication: server vs account tokens
Postmark has two token types, and mixing them up is the classic first 401:
- Server token (
X-Postmark-Server-Tokenheader) - scoped to one "server" (an isolated sending environment with its own streams and stats). Used for sending and most day-to-day calls. - Account token (
X-Postmark-Account-Token) - account-level management: creating servers, managing sender signatures and domains.
Sending with /email
curl -s https://api.postmarkapp.com/email \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "X-Postmark-Server-Token: YOUR_SERVER_TOKEN" \
-d '{
"From": "app@yourdomain.com",
"To": "user@example.com",
"Subject": "Welcome",
"HtmlBody": "<p>Hello!</p>",
"TextBody": "Hello!",
"MessageStream": "outbound"
}'Everything is JSON in and JSON out - no MIME assembly. Attachments are base64 in the payload; /email/batch accepts up to 500 messages per call. The From address must be a verified sender signature or on a domain you've verified with DKIM and Return-Path records.
Message streams: the feature that ages well
Postmark forces separation between transactional and broadcast mail as distinct streams with separate infrastructure and reputation. Password resets never share a queue (or an IP reputation) with your newsletter. If you've ever had marketing blasts tank OTP deliverability at another provider, this is the cure, enforced by design.
Templates
Postmark templates live server-side with a mustache-like syntax (Mustachio) and get their own send endpoint:
curl -s https://api.postmarkapp.com/email/withTemplate \
-H "X-Postmark-Server-Token: YOUR_SERVER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"From": "app@yourdomain.com",
"To": "user@example.com",
"TemplateAlias": "welcome",
"TemplateModel": { "name": "Ada", "action_url": "https://app.example.com/verify" },
"MessageStream": "outbound"
}'Inbound email
Postmark can receive mail too: each server gets an inbound address (something@inbound.postmarkapp.com), or you point your own domain's MX at Postmark. Inbound messages are POSTed to your webhook as parsed JSON - genuinely good parsing, including attachments as base64.
The model's limit: inbound addresses hang off servers, not off a first-class "inbox" you create per user or per agent at runtime. Plus-addressing (inbound+customer1@...) gets you some multiplexing, but if your product needs hundreds of real, distinct addresses that send and receive with threading, you're working against the grain.
Delivery webhooks
Delivery, bounce, spam-complaint, open, and click events each have configurable webhooks with JSON payloads. Verification is by basic auth credentials or IP allowlisting on your endpoint (Postmark publishes its webhook source IPs) - unlike Standard Webhooks HMAC signing, so lock your endpoint down accordingly.
Where Postmark shines - and where it doesn't
Choose Postmark when transactional deliverability is the whole job: password resets, receipts, notifications from your app's domain. The API is small, the docs are excellent, and stream separation keeps reputation clean.
Look elsewhere when:
- You need bulk/marketing volume economics - Postmark's positioning (and pricing) is premium transactional, not cheap blast.
- Inboxes are your product's primitive. Creating an address per customer, per workflow, or per AI agent - each able to send, receive, reply with threading, and stream events - is the job of an inbox-native API. With AgenticEmail,
POST /v1/inboxesreturns a working address; inbound arrives as parsed JSON over signed webhooks or WebSocket; and a hosted MCP server makes the whole thing agent-callable.
For the wider landscape, see the 5 best email APIs for developers and the transactional email API guide.