Mail

This section is entirely focused on promotional/solicitation/invitation email. Transactional messages (event confirmations, gift confirmations, tax receipts, profile updates, membership transactions, and the like) do not count for nor against you in this section as they are sent separately.

Object Model

  • Messages have Message Contacts

  • Message Contacts have Message Contact Activities

  • contacts are intended recipients; contact activities are opens, clicks, bounces, and the like

  • Each Message is associated with a Subscription Category

  • Unsubscribes are recorded as updates to Subscription Preferences, principally to the Subscription Category tied to the triggering message

Process

Email gets sent all the time. Sometimes you'll want to observe performance on a per message basis and other times you're looking to pull data for data quality reasons - regardless of message. We'll aim at the most critical piece first: bad news.

Reminder: many of the API resources we'll reference below have additional optional arguments documented at https://YOUR_ALUMNIQ_DOMAIN/api

These additional arguments have different uses that may fit your model more appropriately.

Opens and Clicks

When things go right you'll have plenty of performance stats to feast on. Pull this whenever you're curious; there's no operational impact to letting it rest in AlumnIQ.

High level message stats:

GET /mail/messages-basic-performance

with optional parameters rangeBegin=yyyy-mm-dd&rangeEnd=yyyy-mm-dd (max 31 days per fetch)

Who was sent a message?

GET /mail/message/recipients/{messageId}

And what did they do once they did?

GET /mail/message-activity with a mix and match of parameters based on what you want to get.

?messageId=MESSAGE_ID for a single message's behaviors

?rangeBegin=yyyy-mm-dd&rangeEnd=yyyy-mm-dd for all activity over a period

?types=hard_bounce,open,click (those three are default). others include soft_bounce,reject,spam

Bounces

Execute this process daily. AlumnIQ is likely not the only source for email sends at your organization and as a result sharing updates with your CRM system is critical.

There are two concepts to keep in mind when thinking about bounce handling:

bounces, which are retained within AlumnIQ and used as a buffer damper on future marketing sends for a period of weeks (0-3 depending on customer's ability to process/clean/refresh email addresses in response to a bounce event). Once that damper window closes we'll not exclude that email address from future sends (until it happens again...)

and

suppressions, which are retained within Mailgun (our outbound mail service provider). Suppressions "latch" when the receiving mail server kicks back a notification of non deliverability and do not clear automatically. Mailgun suppressions will prevent deliveries to the suppressed email addresses until the suppressions are purged.

Because having two resources to look at in order to handle bounce data is inconvenient, we've unified the bounce data behind a single API resource:

GET /mail/all-bounces?rangeBegin=yyyy-mm-dd

rangebegin is required, rangeend is optional. If no rangeend is provided, the end is well past our collective retirement dates (even though, obviously, we can't include future bounces).

A sample response is included in the API dashboard: https://{your_host_name}/api/v1/#unifiedBounceCollectionapi_31F91D382A6B438B0B8FF1B63EA74218

Where else can we see this data?

You can poke the API resource manually under System > Reports and get a very rough CSV equivalent. This is really meant for diagnostics and not regular/routine use.

The type property indicates the source of the bounce - bounceevent is a hard bounce, and a suppression is...that. You'll see that the code and message strings attached to each vary in structure and will generally require some degree of interpretation. We do not include soft bounces in this feed, as they are transient and will always resolve to either a delivery or a hard bounce - hence no immediate action could or should be taken by you with them.

Hard bounces in most situations have a messageId and/or xid attached. Suppressions will never have either one. Both will always have an emailaddress and a timestamp when the bounce/suppression was recorded (adjusted to your campus timezone in the response payload).

You'll notice that all suppressions are returned regardless of rangeBegin - this is deliberate, as suppressions are latched until purged -- including them is a reminder that Mailgun will still block delivery until the purge happens. How do you do that? Read on!

Once you get the data, apply your internal methodology for strikes, deactivating as needed.

And then tell us about it. We need to know you handled these suppressions so that they're not unnecessarily restrained from receving messages in the future.

There are two ways to do it.

Via click ops: Mail > Reporting > Purge Suppressions

or

Via API: PUT /mail/all-bounces

Ideally this is the last thing you do after processing the bounces you fetched from us.

Suppressions provide valuable air cover for your sender reputation. The more times you attempt to deliver to a known-bad account (from their perspective), the more dim their view of your data hygiene and best practices compliance is. If you're handling bounces daily your suppressions should be very small in size and scope (though I'm sure we'll see more in the first couple sends than future ones).

Unsubscribes

Execute this daily. AlumnIQ tries to steer unsubscribes to a specific, message-linked subscription category. Sometimes a recipient will opt out of all categories - thankfully that's rare.

Get the subscriptionCategoryIds for your categories:

GET /mail/subscription-categories

And then the fetch of actual opt out/in changes will make more sense:

GET /mail/subscription-preference-changes?since=YYYY-MM-DD

Unsubscribes are recorded on both opt out and opt-back-in events. This is expressed as a preferenceVal of -1 (for out) and 0 (for back in). 1 is reserved for a future where someone opts to say give me more. We have not yet found the person willing to select that option.

Anyway, the unsubscribe payloads will include email (always) and xid (sometimes). What each election includes depends on the source of the opt out:

  1. If the list used for the message was derived from the AlumnIQ warehouse, then we know the person's email address and xid.

  2. If the list used for the message was derived from an event's registrantsthen xid coverage will be spotty; we'll mostly only have them for people that chose to log in before registering.

  3. If the list used for the message was derived from an excel spreadsheet, we only have the data that was provided to us, which may or may not include xid.

Ideally, one way or another, we would like to have the xid for each message recipient; but AlumnIQ still works, as much as is possible, without it.

All unsubscribe requests will include the email address to which the message was sent. When someone unsubscribes with an xid, based on the list-creation techniques above, it enables unsubscribes to be more robust. We save their unsubscribe request not only with the email address from which they clicked the unsubscribe link, but also their xid; and if there is a different email address associated with their constituent record, the unsubsribe automatically takes effect for that email address as well. Any unsubscribe requests that don't include an xid will only affect the email address from which the unsubscribe link was clicked.

What do I do with unsubscribes?

AlumnIQ will respect and automatically screen unsubscribes from any mass sends going through our system. What you should do with the data is update your CRM system with these categories and preference changes so that partners sending similar communications (cough solicitations) are observing constituent preferences as well.

And if I want to push an unsubscribe or resubscribe to AlumnIQ?

PUT /mail/subscription-preferences with the following parameters:

required numeric subscriptionCategoryId

required numeric preferenceVal (-1 = unsubscribe, 0 = neutral)

required string xid

optional string emailAddress

optional string reason

It's that easy!

Last updated