Are password reset emails "non-transactional"?

I had a user unable to receive their password reset email. I checked the logs at SparkPost and it said because they were on a suppression list there. So I checked SparkPost’s suppression list and it listed the user, but said their action had been to “Unsubscribe” from “non-transactional” emails.

I googled a bit to see what that meant and I got the impression that non-transactional emails aren’t directly requested by the user, e.g. notifications, summaries, newsletters, that type of thing.

I removed the user from this suppression list and they were able to receive Discourse’s password reset email.

Shouldn’t the password reset email have been considered transactional since it was directly requested and gone through anyway? Or do I misunderstand the terms?

That is a question for SparkPost, not us…

1 Like

Okay I thought maybe it was some sort of setting on your end per email. That explains the whole thing then! Thanks.


If they have any guidance on what makes an email “transactional” vs. not, feel free to share. AFAIK we follow best practices for email.

1 Like

According to Remove List-Unsubscribe Header:

The SparkPost API Transmissions endpoint allows you to mark an email as transactional with the attribute options.transactional.

Here it is in their Transmissions API Reference. Obviously this is SparkPost’s API, I’m not sure how the field appears on the actual outgoing email header.

Okay so I checked their template editor and you can send test emails marked as both Transactional or not. So I sent myself one of each. Compared the headers in Beyond Compare.

Only real differences are in DKIM-Signature, X-MSFBL, and List-Unsubscribe. (This points out that the List-Unsubscribe value is a part of the DKIM-Signature, so that explains that.)

After poking around a bit I found an online (because lazy) Base64 decoder that was robust enough to let me view X-MSFBL and List-Unsubscribe.

X-MSFBL contains the following fields: b, customer_id, friendly_from, g, ip_pool, ip_pool_raw, message_id, r, rcpt_meta, rcpt_tags, sending_ip, subaccount_id, template_id, template_version, tenant_id, transmission_id

List-Unsubscribe contains the following fields: customer_id, friendly_from, ip_pool, ip_pool_raw, mailfrom, message_id, rcpt_meta, rcpt_tags, rcpt_to, sending_ip, subaccount_id, template_id, template_version, tenant_id, transmission_id

Same fields have the same values between them.

Anyway the important bit, I compared both X-MSFBL and List-Unsubcribe between the transactional and non-transactional emails and found… ! Essentially nothing. The only differences are sending IPs (meaningless) message_id and transmission_id. (Oh and template_version… it has the name of my test template from SparkPost dashboard and version 1 happens to be transactional, version 2 non-transactional, so that bit was accurately reflected.)

The beginning of X-MSFBL and List-Unsubscribe had some short data I couldn’t base64 decode… so that’s an unknown.

But basically looks like there isn’t any sort of obvious marker in the email header itself that could maybe be used to signal SparkPost. Bummer. :cry: Obviously their API just does what was specified and has no reason to put anything in there since that would be after-the-fact… I think… brain hurting.

1 Like

Akismet hid my post temporarily, heh heh. I’ll just put my edit in a new post:

I’m out of my depth at this point but I’m assuming that Transmissions API is all SparkPost specific stuff and Discourse’s email sending uses something generic… doesn’t detect and do different things for different mailing providers… though I’ve no idea.

Amusing that in their own infographic “Password resets” are the first thing they list for transactional emails. Safe to say they’d have detected that if their system worked that way… the “mark as transactional” thing must just be specific to their outgoing API… darn them. Oh well I’ll live with it. :wink: