From Postmark
A close API shape, a similar streams model, and what actually differs.
The short version
Postmark and OutSend agree on more than they disagree on. Both separate transactional from broadcast sending, both take flat JSON, and both take deliverability seriously. The migration is mostly renaming fields.
Field mapping
| Postmark | OutSend |
|---|---|
From | from |
To | to |
Subject | subject |
HtmlBody | html |
TextBody | text |
ReplyTo | replyTo |
Headers (array of objects) | headers (plain object) |
MessageStream | stream |
X-Postmark-Server-Token header | Authorization: Bearer … |
Postmark’s MessageStream maps onto OutSend’s stream, with the same reasoning behind it:
a broadcast unsubscribe should never stop a password reset from arriving.
Event mapping
| Postmark webhook | OutSend |
|---|---|
Delivery | email.delivered |
Bounce | email.bounced |
SpamComplaint | email.complained |
Open | email.opened |
Click | email.clicked |
SubscriptionChange | email.unsubscribed |
Checklist
- Verify your domain in OutSend. If Postmark already manages your DKIM, you will be publishing a second DKIM record on a different selector — that is fine and expected during a cutover.
- Export suppressions from each Postmark stream and import them into the matching OutSend stream.
- Swap the auth header and rename fields.
- Update webhook handling to verify the HMAC signature.
- Run both in parallel briefly and compare event logs.
What is different
Postmark is a well-run closed service. The differences that might matter to you: OutSend’s core is open source and self-hostable, events keep the receiving provider’s raw payload rather than a normalised summary alone, and we publish our transparency methodology. If none of those matter to you, Postmark is a good product and we would rather say so than pretend otherwise.