Postmark unsubscribe or reactivation notifications on your phone.

Get a low-priority push notification when someone unsubscribes from a Postmark message stream, or an address is suppressed or reactivated.

How it works

Three steps to your first push

STEP 01

Install the recipe

One click in Studio gives you a personal webhook URL.

STEP 02

Paste your URL into Postmark

Add it as a webhook for Subscription Change.

STEP 03

Get a push on your phone

With the text, sound and buttons from the recipe.

Setup

How to set up the Postmark subscription change webhook

  1. Click Install in Studio and sign in. The recipe is added to your account and you get a personal webhook URL.
  2. In Postmark, open your Server, pick the Message Stream (for example Default Transactional Stream) and go to its Webhooks tab.
  3. Click Add webhook and paste your webhook URL as the Webhook URL.https://••••••••/•••••••• your personal URL, shown after install
  4. Tick Subscription Change and save. Postmark checks that the endpoint answers before it starts sending.
  5. Webhooks in Postmark belong to one **Message Stream** of one **Server**, so add this webhook to each stream you want to watch. Unsubscribes mostly happen on broadcast streams.
  6. By default you get a push when:
  7. a recipient unsubscribes (Low priority);
  8. you suppress an address manually (Low) or Postmark does (Normal);
  9. an address is reactivated (Low).
  10. Suppressions caused by a hard bounce or a spam complaint are skipped, because the [bounce](../bounce/) and [spam complaint](../spam-complaint/) recipes already cover them. Add `?all=1` to the webhook URL to get those too:
  11. ```
  12. your webhook URL?all=1
  13. ```
  14. Postmark doesn't sign webhooks. It supports HTTP basic auth in the URL and custom headers, but JustPush doesn't check either yet, so keep your endpoint URL private. When you save the webhook, Postmark checks that the endpoint answers for each event type; that check may produce one test push.
The code

What runs when the webhook arrives

Studio calls handleRequest(request) with the incoming webhook and sends the message it returns. It's yours after install; change anything.

transform.js
1// Postmark → Subscription change webhook
2// Fires when an address is added to or removed from a Message Stream's suppression list.
3// Pushes unsubscribes, manual suppressions and reactivations. Suppressions caused by a hard
4// bounce or spam complaint only push with ?all=1 (the bounce and spam complaint recipes cover those).
5// Docs: https://postmarkapp.com/developer/webhooks/subscription-change-webhook
6
7// Why an address was suppressed, as the recipe describes it.
8const REASONS = {
9 HardBounce: "after a hard bounce",
10 SpamComplaint: "after a spam complaint",
11}
12
13// Look a key up without tripping over inherited names like "toString".
14function pick(table, key, fallback) {
15 return Object.prototype.hasOwnProperty.call(table, key) ? table[key] : fallback
16}
17
18// A trimmed string, or null.
19function text(value) {
20 return typeof value === "string" && value.trim() ? value.trim() : null
21}
22
23function handleRequest(request) {
24 const body = request.body && typeof request.body === "object" ? request.body : {}
25
26 // Guard: only subscription changes with a clear direction.
27 if (body.RecordType !== "SubscriptionChange" || typeof body.SuppressSending !== "boolean") {
28 console.log(`Ignoring Postmark "${body.RecordType ?? "unknown"}" webhook`)
29 return null
30 }
31
32 const who = text(body.Recipient) ?? "An address"
33 const stream = text(body.MessageStream)
34 const where = stream ? ` (${stream} stream)` : ""
35
36 // Reactivated: the address can receive email again.
37 if (!body.SuppressSending) {
38 return {
39 title: "✅ Address reactivated",
40 message: `${who} can receive email again${where}`,
41 topic: "Postmark",
42 priority: -1, // Low: routine list housekeeping
43 }
44 }
45
46 // ?all=1 on the webhook URL also pushes suppressions caused by bounces and complaints.
47 const all = ["1", "true", "yes"].includes(String(request.query?.all ?? "").toLowerCase())
48 const bounceReason = pick(REASONS, body.SuppressionReason, null)
49
50 if (bounceReason) {
51 if (!all) {
52 console.log(`Skipping suppression "${body.SuppressionReason}", covered by the bounce and spam recipes`)
53 return null
54 }
55 return {
56 title: "🚫 Address suppressed",
57 message: `${who} ${bounceReason}${where}`,
58 topic: "Postmark",
59 priority: 0, // Normal: you lost a recipient
60 }
61 }
62
63 // ManualSuppression: an unsubscribe when the recipient did it, otherwise you or Postmark.
64 if (body.Origin === "Recipient") {
65 return {
66 title: "👋 Unsubscribed",
67 message: `${who} unsubscribed${where}`,
68 topic: "Postmark",
69 priority: -1, // Low: routine, but nice to see
70 }
71 }
72
73 return {
74 title: "🚫 Address suppressed",
75 message: `${who} was suppressed ${body.Origin === "Admin" ? "by Postmark" : "manually"}${where}`,
76 topic: "Postmark",
77 priority: body.Origin === "Admin" ? 0 : -1, // Normal when Postmark did it, Low when you did
78 }
79}
Payload

The Postmark SubscriptionChange webhook

This is what Postmark sends to your URL for subscription change. It is a sample, trimmed to the fields recipes use.

SubscriptionChange · sample.json
1{
2 "Tag": "weekly-digest",
3 "Origin": "Recipient",
4 "Metadata": {
5 "customer_id": "cus_1234"
6 },
7 "ServerID": 23,
8 "ChangedAt": "2026-09-29T08:33:54.9070259Z",
9 "MessageID": "883953f4-6105-42a2-a16a-77a8eac79483",
10 "Recipient": "[email protected]",
11 "RecordType": "SubscriptionChange",
12 "MessageStream": "broadcast",
13 "SuppressSending": true,
14 "SuppressionReason": "ManualSuppression"
15}
FAQ

Postmark unsubscribe or reactivation notifications: questions

Does this work on iPhone and Android?

Yes. Install the JustPush app from the App Store or Google Play and sign in. Every phone signed in to your account gets the notification.

Do I need to write code?

No. Install the recipe in Studio, paste your webhook URL into Postmark and you are done. The code is there if you want to change the text, the sound or the buttons.

Can I change what the notification says?

Yes. After install the recipe's code is yours. Edit it in Studio and test it against the sample payload before you save.

What does it cost?

JustPush is free for 30 days. After that it's $19.99 a year, or $39.99 once. There is no extra charge for recipes.

Ready when you are

Postmark on your phone in two minutes.

Install the recipe, paste one URL, done. Free for 30 days, no credit card required.