SMPT Relay Service

Migrating from Postmark: Streams, Templates and Cutover

Postmark migration overview showing separate transactional and broadcast streams merging into one shared sending reputation, and the subdomain split that rebuilds the separation

The migration goes cleanly. Templates ported, credentials swapped, delivery rates holding. Nobody notices anything for about three weeks.

Then a customer says they never received a password reset. Then another. You check, and your transactional mail is landing in spam at Gmail — not because anything broke, but because the monthly newsletter you now send down the same pipe has been quietly teaching Gmail that this sending identity is bulk mail.

Postmark was preventing that. Not as a feature you configured, but as an architecture it enforced. It is the one thing that does not survive the move unless you deliberately rebuild it.

Quick Answer: What Moves and What Rebuilds

AssetMoves or rebuildsEffort
SMTP credentialsMoves — four variablesMinutes
TemplatesExport into your repositoryHours
Suppression dataExport per stream, import firstBefore first send
MessageStream references in codeRemove or remapHours
WebhooksRemap payloads and verificationHours
Stream separationRebuild yourself, with subdomainsThe real work

Everything above the last row is an afternoon. The last row is the migration.

Sequencing—DNS TTL, SPF lookup limits, the percentage ramp, rollback — is covered in our guide to migrating email providers without downtime. Follow that ordering alongside this.

What Postmark Was Doing For You

Postmark's separate transactional and broadcast IP pools with an enforced barrier between them, compared with a single shared sending identity after migration
Two reputations become one. That is the risk, and it is invisible for weeks.

Most providers treat separating transactional from marketing mail as a best practice you may choose to follow. Postmark treats it as a property of the system.

Its message streams documentation states plainly that “transactional and broadcast traffic do not mix in Postmark, including IP ranges.” There is a dedicated transactional IP pool and a dedicated broadcast IP pool, and a message goes down one or the other depending on which stream you send it to.

So if you have been sending password resets through a transactional stream and a newsletter through a broadcast stream, those two have been running on separate sending infrastructure the whole time. One could have a bad month without touching the other.

Move to a provider that does not enforce that, send both through the same credentials, and the two reputations merge. Postmark’s own write-up on the subject describes the failure mode: when you use the same servers and address for both, filters such as Gmail’s may start classifying all of it as bulk. It also cites Google’s own guidance to separate mail by purpose as far as possible — advice Gmail publishes for all senders, not just Postmark customers.

Common Mistake

Treating stream separation as a Postmark feature rather than an email architecture. It reads like vendor functionality, so it gets dropped from the migration plan along with the stream API — and because reputation damage accumulates over weeks rather than appearing on cutover day, the migration looks like a success right up until transactional deliverability starts sliding. By the time anyone connects the two, the newsletter has been training receivers on your sending identity for a month. Rebuild the separation before the first marketing send, not after you see a problem.

Streams Are Not Just a Routing Label

Before you can remove them from your code, it helps to know exactly what you have.

Stream typeWhat it carriesAPI value
TransactionalOne recipient, triggered by a user actionoutbound
BroadcastMany recipients, sent on your schedule; requires an opt-out linkbroadcast

Two details catch people out.

First, the default transactional stream’s API value is outbound, not transactional. If you are grepping for stream references by name, searching for “transactional” will miss most of them.

Second, a Postmark server supports up to 10 streams. Accounts that have been running for a few years often have more than the two obvious ones — a separate stream for a legacy product, one somebody created for testing, one for a specific client. Enumerate them rather than assuming there are two.

Quick Fix

Finding Every Postmark Integration Point

  • Grep for MessageStream — the field name is the most reliable marker
  • Grep for outbound as a string literal; the default transactional stream uses it, not the word “transactional”
  • List every stream on every server, not just the two you expect — up to 10 are possible
  • Note which stream each code path sends to; that mapping becomes your subdomain plan
  • Check your MX records — if Postmark also receives mail for you, that is a second migration

Rebuilding the Separation Yourself

Transactional and marketing mail separated across two sending subdomains, each with its own SPF record, DKIM selector and reputation, both sending through one SMTP relay
What the provider used to enforce, you now configure. Two subdomains, two reputations.

The useful thing is that Postmark has already written the specification for you. Its guidance ranks the options: different From addresses alone is “Good” and a last resort, different IPs is “Better”, and different From addresses, IPs and subdomains together is “Best”.

Separation levelWhat it meansPostmark’s rating
Different From addresses onlySame infrastructure, different senderGood — a last resort
Different sending IPsSeparate infrastructure, shared domainBetter
Different From addresses, IPs and subdomainsFully independent sending identitiesBest

That top tier is what you are reproducing. In practice it means two sending subdomains:

# Two sending identities, two reputations

  txn.yourdomain.com     password resets, receipts, alerts
  news.yourdomain.com    newsletters, product announcements

# Each gets its own SPF record and its own DKIM selector.
# A bad week on news. does not touch txn.
# Keep the root domain out of it entirely — if you ever
# have to burn a sending reputation, burn a subdomain.

Each subdomain publishes its own SPF and DKIM records, so each accumulates its own reputation. This is the part that is genuinely better than what you had: you now control the boundary rather than inheriting it, and you can add a third subdomain for a new mail category without asking anyone.

PhotonConsole authenticates each subdomain independently, so txn. and news. are two sets of DNS records rather than two accounts or two bills.

Note

Resist the temptation to use a different root domain for marketing mail. It looks like the cleanest possible separation and it is a trap — Postmark’s own guidance warns that an unrelated domain “could look like a phishing or spoofing attempt” to receivers, and it also means your marketing mail builds no reputation that benefits your brand. Subdomains of the domain you already send from give you the separation without the suspicion.

Authentication for Two Subdomains

Each subdomain needs its own records. During the parallel run, the subdomain you are migrating authorises both providers:

# txn.yourdomain.com — during migration, both senders
v=spf1 include:spf.mtasv.net include:relay.photonconsole.com ~all

# news.yourdomain.com — new, so only one sender
v=spf1 include:relay.photonconsole.com ~all

# DKIM on independent selectors, so both sign in parallel
photon._domainkey.txn   CNAME  dkim.photonconsole.com

Take Postmark’s exact include from your own account rather than from this article. Then count your lookups: exceeding the ten-term limit in RFC 7208 returns a permerror that fails authentication for both providers at once — the one mistake in a migration that breaks the thing you were trying to protect. Our guide to SPF, DKIM and DMARC covers alignment, and the free email deliverability checker shows what each subdomain currently publishes.

Note that a fresh subdomain starts with no reputation at all. That is not a problem, but it does mean the marketing subdomain needs its own warm-up rather than being switched on at full volume — which is a reason to migrate transactional mail first and marketing second.

Suppression Data

Streams are the organizing unit for almost everything in Postmark, so export suppressions for every stream you send from rather than assuming a single account-wide list.

Quick Fix

Exporting Suppressions Safely

  • Export for every stream on every server — over-collecting costs nothing, missing a list costs deliverability
  • Keep the export in your own storage, not only in the new provider; this is your data
  • Import before the first production send, never after
  • Keep transactional and marketing suppressions mapped to the right subdomain — an unsubscribe from the newsletter is not a reason to stop sending receipts
  • Re-export on your final day; addresses that bounced during the ramp exist only in Postmark

That fourth point matters more here than in other migrations. Because your streams were separate, your suppression data is separate too, and flattening it into one list means a marketing unsubscribe can silently block a password reset. Keep the lists distinct in the same way you keep the subdomains distinct. Our guide to reducing bounce rate explains why importing before the first send matters so much on a new sending identity.

Templates

Export them into your repository rather than into another provider’s template store.

Postmark supports layouts that templates inherit from, so check whether yours use one — a template exported without its layout renders without the wrapper, which is easy to miss in a quick visual check because the content all appears to be there. Flatten the layout into each template, or reproduce the layout mechanism in whatever renders your mail now.

Templates under version control are reviewable, diffable and testable in CI, which also means the next migration is a configuration change rather than a project. PhotonConsole sends whatever HTML your application renders, so there is no second template store to keep in sync.

Then test every template against payloads with missing and null fields before sending one to a real recipient. Renderers differ in how they treat an undefined variable: some output nothing, some output the literal placeholder, and finding out which on a live password reset is an unpleasant way to learn.

If Postmark Also Receives Your Mail

Check your MX records before you plan anything. If they point at Postmark, inbound processing is live and it is a separate migration from sending — with its own cutover, its own testing, and its own failure mode, which is silent in both directions.

The pattern for reimplementing inbound handling as application code is covered in our guide to migrating from Mailgun, where inbound routing is the central problem. The same approach applies: list the rules, express them as an ordered set with an explicit catch-all, and move inbound only after sending is settled.

Validation and Cutover

Before moving production traffic, confirm three things with real sends:

  • Each subdomain authenticates independently. MXToolbox confirms the records resolve; Mail Tester scores an end-to-end send from each one separately.
  • Templates render correctly, including with missing variables and with the layout applied.
  • Webhook events parse, tested by triggering a real bounce to a known-invalid address.

Then migrate in this order, which is specific to Postmark and worth following:

  1. Transactional first, ramped by percentage with Postmark still live. This is your highest-stakes mail, so it gets the full parallel-run treatment per the migration guide.
  2. Marketing second, on its own subdomain, warmed up from low volume. It is lower-stakes and the subdomain is new, so it needs the ramp for a different reason.
  3. Inbound last, if applicable, as a separate change.

Doing transactional first is the opposite of what feels safe — most people want to test on the mail that matters least. But marketing mail from a cold subdomain will have a rough first week regardless, and you do not want to be diagnosing that at the same time as a transactional cutover. Separate the two problems in time.

Both providers stay live throughout, and PhotonConsole issues SMTP credentials on signup, so the transactional path can be live and testable the same day you start building subdomains. Pricing includes 5,000 free emails a month, which covers the whole parallel-running phase without a second bill arriving mid-migration.

Pro Tips

  • Grep for outbound, not “transactional”. The default stream’s API value is the word nobody expects.
  • Enumerate every stream. Up to 10 per server, and old accounts accumulate them.
  • Build the subdomains before you touch any code. DNS propagation is the slowest part and it costs nothing to start early.
  • Keep marketing and transactional suppressions separate. Flattening them lets an unsubscribe block a receipt.
  • Never send marketing mail from the root domain. If a reputation has to be burned, burn a subdomain.
  • Check for template layouts. A template exported without its layout looks almost right, which is the problem.
  • Transactional first, marketing second. Do not debug a cold subdomain and a cutover in the same week.

Related Reading

Frequently Asked Questions

What is the hardest part of leaving Postmark?

Rebuilding stream separation. Postmark keeps transactional and broadcast mail on separate IP pools automatically; most providers do not, so you reproduce that separation yourself using two sending subdomains.

What are Postmark message streams?

Routing targets that determine which sending infrastructure a message uses. Transactional streams carry single-recipient triggered mail; broadcast streams carry scheduled multi-recipient mail and require an opt-out link.

Does Postmark really keep the two types of mail separate?

Yes. Postmark’s documentation states that transactional and broadcast traffic do not mix, including IP ranges, with a dedicated IP pool for each.

Why does my transactional deliverability drop weeks after migrating?

Because marketing and transactional mail now share one sending identity, and receivers gradually learn to treat the whole identity as bulk. The damage accumulates rather than appearing on cutover day.

What is the API value for Postmark’s default transactional stream?

outbound. Searching your codebase for “transactional” will miss most stream references.

How many message streams can a Postmark server have?

Up to 10. Enumerate them before migrating rather than assuming you have only transactional and broadcast.

Should I use a separate domain for marketing email instead of a subdomain?

No. An unrelated domain can look like spoofing to receivers and builds no reputation for your brand. Use subdomains of the domain you already send from.

Should I migrate transactional or marketing email first?

Transactional first, with a full parallel run. Marketing second on a fresh subdomain that needs its own warm-up, so you are not diagnosing two different problems at once.

Conclusion

Postmark migrations do not fail on cutover day. They fail three weeks later, which is far harder to diagnose.

The reason is that Postmark’s most valuable property is not a feature you would think to port. It is an architecture: transactional and broadcast mail on separate IP pools, enforced by the platform rather than configured by you. Drop it, and two reputations that were insulated from each other become one, and your newsletter starts deciding whether your password resets reach the inbox.

So the migration has one central task, and it is not the credential swap. Build two sending subdomains, authenticate each independently, keep their suppression lists distinct, and move transactional mail first with marketing following on its own warm-up. That reproduces what Postmark was doing — and puts the boundary under your control, where you can add a third category without asking a vendor.

Everything else is a few hours: templates into version control, MessageStream references removed, webhooks remapped. A reliable SMTP provider handles the sending with standard SMTP and a flat per-thousand rate, and the separation ends up documented in your own DNS rather than assumed from a platform you no longer use.

Read More

phoconadmin

About Author

Leave a comment

Your email address will not be published. Required fields are marked *

You may also like

Email Deliverability SMPT Relay Service

SMTP Authentication Error: Causes & Solutions (Fix SMTP Error 535 Step-by-Step)

Your transactional emails have stopped sending. OTP codes are not reaching users. Password reset emails are failing silently. Your application
Test an SMTP Server testing workflow showing connection check, authentication validation, and email delivery verification from application to inbox
Email Deliverability SMPT Relay Service

How to Test an SMTP Server (Step-by-Step Guide)

Learn how to test an SMTP server step by step, fix common errors, and ensure reliable email delivery with proper