Skip to main content

Postmark (ActiveCampaign): Complete Technical Guide to Transactional Email

By CaptainDNS
Published on January 28, 2026

Postmark Dashboard with Message Streams and DKIM DNS configuration
TL;DR
  • Postmark, a transactional email specialist acquired by ActiveCampaign in 2022, focuses on exceptional deliverability with strict transactional/broadcast separation via Message Streams.
  • Simple REST API at api.postmarkapp.com with X-Postmark-Server-Token header, 50 recipients max per email, 500 messages per batch.
  • 1024-bit DKIM with timestamped selector ([timestamp]pm._domainkey), quarterly manual rotation recommended.
  • Custom Return-Path via CNAME pm-bounces.captaindns.com to pm.mtasv.net for relaxed SPF DMARC alignment only (not strict).
  • Dedicated IP at $50/month starting from 300K emails/month, automatic warm-up over 3-6 weeks.
  • Plans starting at $15/month for 10K emails (Basic), Free Developer plan limited to 100 emails/month.

Introduction

Postmark has built an excellent reputation in transactional email with a clear philosophy: deliverability above all else. Acquired by ActiveCampaign in May 2022, the service remains a standalone product, keeping its team and technical DNA intact. The platform processes billions of emails with an exclusive focus on transactional messages (order confirmations, password resets, notifications).

Postmark's distinctive feature is its strict separation between transactional and broadcast via Message Streams. This architecture ensures your critical emails are never impacted by marketing campaigns. The shared IP pool is actively monitored to maintain an impeccable reputation.

This guide is intended for developers, DevOps engineers and system architects seeking to integrate Postmark with a complete understanding of the infrastructure: DNS configuration, API vs SMTP choice, IP management, webhooks and technical limits.

REST API vs SMTP Relay: architecture and integration choices

Postmark offers two integration methods, each suited to specific use cases.

Comparison between Postmark REST API and SMTP Relay

Technical comparison

CriteriaREST APISMTP Relay
EndpointPOST https://api.postmarkapp.com/emailsmtp.postmarkapp.com ports 587/2525
AuthenticationHeader X-Postmark-Server-TokenUsername: API key / Password: API key
Recipients/email50 max (To + Cc + Bcc)50 max
Batch500 messages/call, 50 MB max1 email per connection
Max size10 MB per email10 MB per email
TemplatesMustachio (Handlebars-like)Inline content only
SchedulingNot natively supportedNot natively supported
TrackingVia JSON parametersVia X-PM-* headers
Ideal use caseModern apps, batch, templatesLegacy, CMS, existing mail servers

When to choose REST API?

The REST API is the recommended method for any new integration. It offers precise control over every aspect of sending.

Main endpoint: POST https://api.postmarkapp.com/email

Required headers:

Content-Type: application/json
Accept: application/json
X-Postmark-Server-Token: your-server-token

Complete sending example:

curl "https://api.postmarkapp.com/email" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Postmark-Server-Token: your-server-token" \
  -d '{
    "From": "notifications@captaindns.com",
    "To": "client@captaindns.com",
    "Subject": "Your DNS analysis is ready",
    "TextBody": "Hello, your DNS report is available.",
    "HtmlBody": "<html><body><strong>Hello</strong>, your DNS report is available.</body></html>",
    "Tag": "dns-report",
    "TrackOpens": true,
    "TrackLinks": "HtmlAndText",
    "MessageStream": "outbound",
    "Metadata": {
      "report_id": "RPT-12345",
      "user_id": "USR-789"
    }
  }'

Expected response (200 OK):

{
  "To": "client@captaindns.com",
  "SubmittedAt": "2026-01-28T10:30:00.1234567-05:00",
  "MessageID": "b7bc2f4a-e38e-4336-af7d-e6c392c2f817",
  "ErrorCode": 0,
  "Message": "OK"
}

Key limits:

  • Rate limit: not explicitly published, internal monitoring
  • Recipients: 50 max per email (To + Cc + Bcc)
  • Batch: 500 messages per call, 50 MB total
  • Email size: 10 MB max

Official SDKs: Ruby, .NET, Java, PHP, Node.js. No official Python SDK (use postmarker or python-postmark).

When to choose SMTP Relay?

SMTP Relay is ideal for legacy systems or applications that only support SMTP.

Official configuration:

# Transactional
SMTP server: smtp.postmarkapp.com
Port: 587 (recommended) or 2525 (fallback)

# Broadcast
SMTP server: smtp-broadcasts.postmarkapp.com
Port: 587 or 2525

# Authentication
Username: your-server-api-token
Password: your-server-api-token

Available ports:

PortSupportNotes
25YesStandard SMTP
465NoImplicit TLS not supported
587YesRecommended - submission port
2525YesAlternative port

Authentication methods: CRAM-MD5 (recommended), DIGEST-MD5, PLAIN, LOGIN.

Proprietary X-PM- headers*:

HeaderUsageExample
X-PM-TagCategorizationX-PM-Tag: password-reset
X-PM-Message-StreamSpecify streamX-PM-Message-Stream: outbound
X-PM-Metadata-*Custom metadataX-PM-Metadata-user-id: 12345
X-PM-TrackOpensOpen trackingX-PM-TrackOpens: true
X-PM-TrackLinksLink trackingX-PM-TrackLinks: HtmlAndText

Domain Authentication: DKIM, Return-Path and DMARC alignment

Domain authentication in Postmark relies on DKIM and a customizable Return-Path. Configuration is done in Sender Signatures or Domain Authentication.

DNS authentication flow with Postmark

DKIM configuration

Postmark generates a 1024-bit DKIM key with a unique timestamp-based selector.

Selector format: [timestamp]pm._domainkey.captaindns.com

Selector examples:

  • 20260128pm._domainkey.captaindns.com
  • jan2026pm._domainkey.captaindns.com

DNS record to create:

Type: TXT
Hostname: 20260128pm._domainkey.captaindns.com
Value: k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO...

Characteristics:

  • Key size: 1024 bits (not 2048)
  • Rotation: manual, quarterly recommended
  • Rotation API: POST /domains/{domainid}/rotatedkim

Rotation uses the two-selector system: Postmark prepares the new selector before switching, ensuring a seamless transition.

SPF: required or not?

SPF is no longer required for Postmark. Here's why:

By default, Postmark uses its own domain for the Return-Path:

Return-Path: <pm_bounces@pm.mtasv.net>

Receiving servers check SPF against the Return-Path domain (pm.mtasv.net), not your From domain (captaindns.com). Your emails automatically pass SPF without any DNS changes on your end.

Optional include (if you want to be explicit):

v=spf1 a mx include:spf.mtasv.net ~all

Custom Return-Path and DMARC alignment

To achieve SPF DMARC alignment, you need to configure a custom Return-Path.

Required DNS record:

Type: CNAME
Hostname: pm-bounces.captaindns.com
Value: pm.mtasv.net

After configuration:

Return-Path: <pm_bounces@pm-bounces.captaindns.com>

Impact on DMARC alignment:

ConfigurationSPF PassDMARC Alignment
Default Return-PathYes (Postmark domain)No - Fails
Custom Return-PathYes (client subdomain)Yes - Relaxed only

Critical point: strict alignment (aspf=s) is not possible with Postmark because the Return-Path always uses a subdomain (pm-bounces.captaindns.com does not equal captaindns.com).

Recommended strategy: rely on DKIM for DMARC alignment, which supports strict mode (adkim=s).

Complete DNS summary table

RecordTypeHostnameValueRequired
DKIMTXT[timestamp]pm._domainkey.captaindns.comk=rsa; p=[public-key]Yes - Recommended
Return-PathCNAMEpm-bounces.captaindns.compm.mtasv.netFor DMARC alignment
Link TrackingCNAME[custom].captaindns.com[postmark-value]Optional
SPFTXTcaptaindns.comv=spf1 include:spf.mtasv.net ~allNo - Not required

Message Streams: transactional vs broadcast

Postmark enforces a strict separation between transactional and broadcast emails via Message Streams. This architecture protects the reputation of your critical emails.

Stream architecture

AspectTransactionalBroadcast
UsageUser-triggered emailsBulk emails (newsletters)
SMTP hostsmtp.postmarkapp.comsmtp-broadcasts.postmarkapp.com
Unsubscribe linkOptionalRequired
InfrastructureDedicated IP poolSeparate IP pool
Default streamoutboundbroadcast

For Broadcast streams, the unsubscribe link is mandatory:

<a href="{{{ pm:unsubscribe }}}">Unsubscribe</a>

Unsubscribe handling:

  • UnsubscribeHandlingType: "Postmark": handled automatically
  • UnsubscribeHandlingType: "None": handle manually

Message Stream limits

ResourceLimit
Streams per Server10 max (contact support for more)
Inbound Streams per Server1 only
Stream name100 characters max
Archived streamsDeleted after 45 days

Shared IP vs dedicated IP

Shared IP pool (all plans)

By default, all Postmark customers use a high-reputation shared IP pool.

Postmark philosophy: "A high-quality, high-reputation IP pool provides better and more reliable deliverability" for most senders.

Characteristics:

  • Actively monitored pool
  • Automatic blacklist alerts
  • No warm-up needed
  • Suitable for most volumes

Dedicated IP

For high volumes, Postmark offers dedicated IPs.

CriteriaValue
Minimum volume300,000 emails/month
Cost$50/IP/month (no setup fee)
Additional IP100,000+ messages/day required
Warm-upAutomatic, 3-6 weeks
OverflowRouted via shared pool during warm-up

Automatic warm-up:

  • Daily limits set by Postmark
  • Adjustment based on receiver response
  • Excess volume sent via shared pool
  • Continuous monitoring by Postmark team

Re-warmup required: if volume drops below 20,000 messages/week for 4 consecutive weeks.

Reverse DNS: managed by Postmark (not customizable by customer).

2026 Pricing

Plans and prices

PlanPrice/month (10K)Overage /1000ServersDomainsStreamsDedicated IP
Free Developer$0N/A101030No
Basic$15$1.805515No
Pro$16.50$1.30101030Yes (300K+)
Platform$18$1.20UnlimitedUnlimitedUnlimitedYes (300K+)

Free Developer plan limits:

  • 100 emails/month (hard cap)
  • No overage possible
  • Ideal for testing and development

Scaling by volume

Monthly volumeApproximate price
10,000$15-18/month
50,000$50-60/month
125,000~$100/month
300,000~$200/month
700,000~$400/month
5,000,000+Custom pricing

Optional add-ons

Add-onPrice
Dedicated IP$50/month/IP
Custom Activity RetentionStarting at $5/month
DMARC DigestsStarting at $14/month/domain

Counting rules

  • Each sent message = 1 email
  • Each Cc/Bcc address = 1 additional email
  • Sandbox messages = counted
  • Unused emails = not rolled over

Webhooks and events

Postmark offers a comprehensive webhook system to track the lifecycle of your emails.

Postmark webhook architecture

Available events

EventDescription
DeliveryEmail delivered to receiving server
BounceEmail bounced (hard, soft, transient)
OpenRecipient opened the email
ClickRecipient clicked a link
SpamComplaintEmail marked as spam
SubscriptionChangeAdded/removed from Suppression list
InboundInbound email received and parsed

Bounce payload example

{
  "RecordType": "Bounce",
  "ID": 692560173,
  "Type": "HardBounce",
  "TypeCode": 1,
  "Name": "Hard bounce",
  "Tag": "dns-report",
  "MessageID": "2c1b63fe-43f2-4db5-91b0-8bdfa44a9316",
  "ServerID": 23,
  "MessageStream": "outbound",
  "Description": "The server was unable to deliver your message",
  "Email": "invalid@captaindns.com",
  "From": "notifications@captaindns.com",
  "BouncedAt": "2026-01-28T16:09:19Z",
  "Inactive": true,
  "CanActivate": true
}

Retry policy

Webhook typeRetry policy
Bounce, Inbound1 min > 5 min > 10 min (x3) > 15 min > 30 min > 1h > 2h > 6h = 10 retries over ~10.5h
Click, Open, Delivery1 min > 5 min > 15 min = 3 retries

Important: an HTTP 403 response immediately stops retries.

Security: HMAC-SHA256 signature

Each webhook is signed with the X-Postmark-Signature header.

Verification (Node.js):

const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const computedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('base64');
  return crypto.timingSafeEqual(
    Buffer.from(computedSignature),
    Buffer.from(signature)
  );
}

Configuration via API

curl "https://api.postmarkapp.com/webhooks" \
  -X POST \
  -H "Content-Type: application/json" \
  -H "X-Postmark-Server-Token: your-server-token" \
  -d '{
    "Url": "https://captaindns.com/webhooks/postmark",
    "MessageStream": "outbound",
    "Triggers": {
      "Delivery": { "Enabled": true },
      "Bounce": { "Enabled": true, "IncludeContent": false },
      "SpamComplaint": { "Enabled": true },
      "Open": { "Enabled": true, "PostFirstOpenOnly": true },
      "Click": { "Enabled": true }
    }
  }'

Technical limits and quotas

Message size

LimitValue
Max email size (API)10 MB total
Max batch size (Batch API)50 MB total
TextBody / HtmlBody5 MB each
Message storage1 MB (truncated beyond)

API quotas

ResourceLimit
Recipients per email50 max (To + Cc + Bcc)
Messages per batch500 max
Webhook URLs per stream10 max
Tag size1,000 characters
Bounce/message search10,000 results max

Data retention

TypeDuration
Default retention45 days
Minimum retention7 days
Maximum retention365 days (add-on)
Bounce dumps30 days max
Aggregated statisticsIndefinitely
Suppression listIndefinitely

Templates with Mustachio

Postmark uses Mustachio, a templating language based on Mustache with specific enhancements.

Basic syntax

<!-- Variable with HTML escaping -->
{{ firstname }}

<!-- Variable without escaping (raw) -->
{{{ html_content }}}

<!-- Dot notation -->
{{ order.number }}

Conditions (truthy/falsy blocks)

{{#has_discount}}
  <p>Your discount: {{ discount_amount }}</p>
{{/has_discount}}

{{^has_discount}}
  <p>No discount applied</p>
{{/has_discount}}

Loops

{{#each items}}
  <li>{{ name }} - ${{ price }}</li>
{{/each}}

Limitations:

  • No explicit if/else syntax
  • Complex logic not supported
  • <link> tags forbidden in <head>
  • CSS automatically inlined on send

Security and compliance

Certifications

CertificationDetail
SOC 2 Type 2No - certifications at data center level (AWS, Deft)
ISO 27017/27018Via AWS
PCI DSS Level 1Via Stripe (payments)

GDPR

AspectDetail
DPA availableYes - with SCCs
DPA URLhttps://postmarkapp.com/dpa
Data locationUS (no EU option)
EU representativeEU-REP.Global

HIPAA

AspectDetail
HIPAA compliantNO
BAA availableNO

Postmark explicitly states: "Postmark is not HIPAA-compliant so we do not recommend using our platform if you need to send HIPAA-compliant emails".

Account authentication

FeatureAvailability
2FAYes - All plans
SSO/SAMLNo - Not available

Action plan: integrate Postmark step by step

  1. Create an account at https://account.postmarkapp.com/sign_up
  2. Request approval via "Request approval" (~24h manual review)
  3. Verify your domain (individual Sender Signature or full domain)
  4. Configure DNS records:
    • DKIM: TXT [timestamp]pm._domainkey.captaindns.com
    • Return-Path: CNAME pm-bounces.captaindns.com to pm.mtasv.net
  5. Create a Server API Token in Settings > API Tokens
  6. Test with the test token: use POSTMARK_API_TEST as token to validate without sending
  7. Configure webhooks for bounces and spam complaints
  8. Monitor via the Activity Feed and statistics

Technical guides: other transactional email platforms

Discover our complete guides for other transactional email solutions:

FAQ

Is Postmark suitable for email marketing?

No, Postmark specializes in transactional email. Broadcast emails (newsletters, announcements) are supported via separate Message Streams, but the platform does not offer advanced marketing features (segmentation, A/B testing, automation). For marketing, consider dedicated solutions or the parent platform ActiveCampaign.

What is the difference between Postmark and SendGrid?

Postmark focuses exclusively on transactional deliverability with a tightly controlled IP pool. SendGrid offers more flexibility (2048-bit DKIM, published rate limits, more SDKs) but with a more generalist positioning. Postmark uses 1024-bit DKIM keys and does not explicitly publish its rate limits.

Can you use Postmark with a strict DMARC policy?

Yes, via DKIM. DKIM alignment supports strict mode (adkim=s). However, SPF alignment only works in relaxed mode (aspf=r) because the Return-Path uses a subdomain. Configure your DMARC policy to rely on DKIM: p=reject; adkim=s; aspf=r.

How much does a dedicated IP cost at Postmark?

$50/month per IP, with no setup fee. Requirement: send at least 300,000 emails/month. Warm-up is automatic over 3-6 weeks. For an additional IP, you need to exceed 100,000 messages/day.

Is there an official Python SDK for Postmark?

No, Postmark does not maintain an official Python SDK. Recommended community alternatives are postmarker and python-postmark. Official SDKs cover Ruby, .NET, Java, PHP and Node.js.

Is Postmark HIPAA compliant?

No. Postmark explicitly refuses to sign BAAs (Business Associate Agreements). If you need to send PHI (Protected Health Information), use another HIPAA-compliant solution.

Glossary

  • Message Stream: separate sending flow that isolates transactional emails from broadcasts, each with its own IP pool and metrics
  • Sender Signature: verification of an individual sender email address, alternative to full domain verification
  • Return-Path: bounce address (Envelope From) used by receiving servers for SPF and bounce notifications
  • Mustachio: Postmark's templating language based on Mustache, with support for conditions, loops and variables

Official sources

Similar articles