Postmark
Postmark focuses purely on transactional email and is known for fast, reliable inbox delivery. It separates transactional and bulk traffic into message streams, which protects the reputation of your important emails.
Choose Postmark when deliverability and speed of transactional mail (password resets, receipts, form confirmations) matter most and you don’t mind that Postmark reviews new accounts before they can send freely. Postmark does not allow cold or purchased-list marketing. See the services overview for alternatives.
Prerequisites
Section titled “Prerequisites”- A Postmark account and a server (Postmark’s name for a project), e.g. “Website”.
- A verified sender: either a Sender Signature for a single address or, better, a verified domain (Sender Signatures → Add Domain or Signature).
- Account approval before sending to recipients outside your own domain – see Sandbox & limits.
- The Server API token of that server (Servers → your server → API Tokens). A server token can only send and read data of its own server – that is the least-privilege option. Do not use the Account API token.
Connect in Frontmail
Section titled “Connect in Frontmail”- Open Email services → Add service → Postmark.
- Fill in the fields:
| Field | Where to find it | Example |
|---|---|---|
| Server API token | Servers → your server → API Tokens | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| Message stream | Servers → your server → Message Streams; use a Transactional stream | outbound |
| Webhook username | Optional – the Basic auth username you set on the Postmark webhook | frontmail |
| Webhook password | Optional – the matching password | s3cr3t-long-random |
| Max emails per second | Optional; default 10/s | 10 |
- Click Verify & save – Frontmail reads the server details with the token.
- The service is saved once the check passes. Credentials are encrypted with AWS KMS envelope encryption.
DNS: SPF, DKIM and DMARC
Section titled “DNS: SPF, DKIM and DMARC”After you add a domain, Postmark shows two records to publish:
; DKIM – the selector contains a date-based part, copy it from Postmark20240101123456pm._domainkey.example.com. TXT "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GN…"
; Custom Return-Path – makes SPF align with your domainpm-bounces.example.com. CNAME pm.mtasv.net.
; DMARC – monitoring first_dmarc.example.com. TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"- The DKIM host looks like
<timestamp>pm._domainkey; always copy the exact value from Postmark. - With the Return-Path CNAME to
pm.mtasv.net, you do not need to add Postmark to your root SPF record – SPF is checked on the Return-Path subdomain, which Postmark manages. - Click Verify next to each record in Postmark. Tighten DMARC to
p=quarantine/p=rejectonce reports are clean.
Regions
Section titled “Regions”Postmark has a single API endpoint (api.postmarkapp.com) and no region to choose. Data is processed in the US; check Postmark’s DPA if EU data residency matters to you.
Sandbox & limits
Section titled “Sandbox & limits”- Pending approval: a new account can send only to addresses on the same domain as the verified sender until Postmark approves it. Attempts to send elsewhere fail with error code
412. Request approval in the Postmark dashboard; it is usually handled within a business day. - Test mode: the special token
POSTMARK_API_TESTaccepts messages without sending them – useful for local testing, but Frontmail’s Test connection will reject it because it has no server behind it. - Free developer plan: 100 emails per month.
- Postmark keeps its own list of inactive recipients (hard bounces, complaints) per stream; sending to them fails with code
406.
Webhooks (delivery tracking)
Section titled “Webhooks (delivery tracking)”Postmark webhooks are configured per message stream.
-
Copy the webhook URL from the service page in Frontmail (copy button):
https://api.frontmail.dev/webhooks/providers/postmark/<token> -
In Postmark open Servers → your server → the stream (e.g. Default Transactional Stream) → Webhooks → Add webhook, paste the URL and select the events:
| Postmark event | Frontmail event |
|---|---|
| Delivery | delivered |
Bounce – hard (HardBounce, BadEmailAddress, ManuallyDeactivated) |
bounced – added to the suppression list |
Bounce – soft/transient (SoftBounce, Transient, DnsError) |
recorded on the message |
| Spam Complaint | complained – added to the suppression list |
| Open | opened (enable open tracking on the stream) |
| Link Click | clicked (enable link tracking on the stream) |
- Protect the webhook with Basic auth (recommended): in the webhook form fill in Basic auth credentials (username + a long random password) and enter the same values in the Frontmail service fields Webhook username / Webhook password.
Signature verification: Postmark does not sign webhook payloads. The secret token in the URL identifies the service, and when you set a webhook password Frontmail rejects any request without matching Basic auth credentials. Use the Send test button in Postmark to check it.
Frontmail adds an X-Frontmail-Message-Id header to each message so events match the right message.
Common errors
Section titled “Common errors”- auth – the service is broken (invalid token, unconfirmed sender, account not approved, unknown stream). The service is marked
unhealthy; the owner gets an email and a dashboard banner. A fallback service on the template takes over; without one the credit is refunded and the message waits in the hold queue asheld_service_error, sent automatically after you fix the service (re-checked on save and by the daily health check). - permanent – this message can’t be sent (invalid or inactive recipient, validation error). Fallback service if configured, otherwise
failedand the credit refunded. - transient – 5xx, timeouts, 429. Retried with exponential backoff; when retries run out
failedand refunded.
| Postmark error | Class | What to do |
|---|---|---|
10 – Bad or missing Server API token (HTTP 401) |
auth | Copy the Server token (not the Account token) again. |
400 – Sender signature not defined for From address |
auth | Verify the From domain/address in Sender Signatures, or change the template’s From. |
401 – Sender signature not confirmed |
auth | Click the confirmation link Postmark sent to the sender address. |
412 – Account pending approval, recipients restricted to your domain |
auth | Request account approval in Postmark. |
1235 – Message stream not found |
auth | Fix the Message stream ID (e.g. outbound). |
406 – Inactive recipient |
permanent | The address bounced or complained earlier; Postmark suppresses it. Reactivate it in Postmark only if you’re sure. |
300 / 422 – Invalid email request / invalid address |
permanent | See invalid recipient. |
HTTP 429 / 500 / 503 |
transient | Rate limit or outage – Frontmail retries automatically. |
Checklist
Section titled “Checklist”- Domain verified in Postmark (DKIM TXT + Return-Path CNAME
pm.mtasv.net) - DMARC record published, starting with
p=none - Account approved by Postmark
- Server API token (not Account token) entered
- Message stream = a transactional stream (
outbound) - Test connection passes
- Webhook on the stream with Delivery, Bounce, Spam Complaint (+ Open/Click)
- Basic auth on the webhook, same credentials in Frontmail