Mailbox full? Say goodbye to improve deliverability

When a user’s email inbox is full, any email you send to that user won’t be delivered; it will be rejected by that user’s mailbox provider.

In many cases, this is a temporary problem; users who are actively checking their email will delete or archive their emails, allowing them to begin receiving email again.

But users who are no longer checking their inbox won’t ever delete or archive their emails, and so won’t ever be able to receive email again.

When one of your emails is rejected due to a full inbox, this is called a soft bounce. Soft bounces should not be confused with hard bounces, which are due to an email address being permanently unmailable (like emailing an address that doesn’t exist).

ActionKit only reports hard bounces on the Mailing Report screen, but we do track these “inbox full” soft bounces in our database.

ActionKit’s Soft Bounce Handling system allows you to improve your email deliverability by identifying users who have repeatedly had many “inbox full” soft bounces in a short period of time and unsubscribe these users.

How it works

Soft Bounce Handling is configurable. You can choose how many “inbox full” soft bounces a user can have in a given period before they’re unsubscribed.

For example, in the screenshot below, a user would need to have 3 or more “inbox full” soft bounces in a 14-day period in order to be subscribed — a user would NOT be subscribed immediately the first time their inbox became full.

Soft Bounce Handling Default Settings
Soft Bounce Handling Default Settings

If you send very infrequently, you may wish to adjust your settings accordingly. For example, if users don’t commonly receive at least 3 emails from you in a 14-day period, the above settings won’t be very helpful, and setting a longer period like 21 days may be more useful.

Less commonly, but senders who send to their users multiple times per day may also want to adjust their settings to require more soft bounces over a given period before being unsubscribed.

Off unless checked!

Keep in mind that Soft Bounce Handling is off unless the “Remove Repeat Soft Bouncers” checkbox is checked, and the “Max soft bounces” and “Period length” settings won’t do anything.

Why does this matter?

Mailbox providers determine your sender reputation based on a variety of factors, but it mainly boils down to how users are engaging with your emails: opening, clicking, and reading them. Repeatedly sending to users whose inboxes are full harms your sender reputation a tiny bit, and not sending to users whose inboxes are abandoned helps your sender reputation quite a bit.

This setting can lead to small and incremental improvements in your sender reputation. For more details about inbox placement and deliverability, and especially for more impactful deliverability tips, make sure to check out our explainer video.

Be sure to also check out our post on Bounce/Delay metrics and how you can use them as an early-warning system to monitor your deliverability.

Keep an eye on deliverability

The Bounce/Delay Metrics screen is meant as an early-warning system for your mailing deliverability, to help identify small problems with your mailing’s deliverability and allow you to make corrections before small problems become large.

If you’re new to mailing deliverability or want a refresher on the fundamentals and how mailbox providers like Gmail determine whether your mail gets delivered to the inbox or spam, see our video on Deliverability.

When sending mailings, we expect all of our email to be delivered. Usually that’s the case, but there are common reasons why some proportion of your emails don’t get delivered:

  • Some bounces are to be expected, even for senders with perfect sender reputations. For example, if a recipient user has a full mailbox, sending them an email will result in a soft bounce. Soft bounces are typically transient issues, so they clear up on their own.
  • Soft bounces shouldn’t be confused with hard bounces, which are permanent, irrecoverable failures to deliver. Most hard bounces are from emailing an address that no longer exists.

Soft bounces aren’t typically harmful to your sender reputation, but hard bounces are — that’s why ActionKit automatically unsubscribes users who hard bounce.


When sending mailings, we expect all of our email to be delivered pretty much immediately. Usually that’s the case, but there are some common reasons why some proportion of your emails might get delivered late (delayed).

Important note: Bounces and delays happen on every bulk mailing system, not just on ActionKit!

Why Delays Happen

Delays are common, especially during your warmup (for new clients) or when sending more mailing volume to a given mailbox provider. Each mailbox provider will allow you to send a certain number of emails in a period of time, based on your sender reputation. If you send too many emails too quickly, a mailbox provider like Microsoft may suspect that you’re sending spam, and delay your messages.

Groups with better sender reputations at the various mailbox providers will be able to send more email in a short period of time, as they’re more trusted. Groups with a new or weak reputation won’t be able to send a lot of email without having that email delayed by the mailbox providers. When your emails are delayed, they’re more likely to end up in spam when they ultimately get delivered, because the mailbox provider is already looking at your email with more scrutiny.

The exact figures for how many emails you can send and how quickly aren’t obvious or transparent — if they were, spammers would be able to easily bypass the mailbox providers’ spam checks and get spam delivered to your inbox.

Looking at the Deliverability by Mailbox Provider Report

In this report, we have a problem worth paying attention to at Comcast, and possibly at another domain.
In this report, we have a problem worth paying attention to at Comcast, and possibly at another domain.

When looking at delay reports, don’t worry about very small numbers of delays, or if a tiny portion of the recipients at a given provider were delayed. But if you see a large portion of emails at a given provider were delayed, or a large portion of your overall send being delayed, pay attention — that’s an early sign that something’s wrong.

What to do when you see delays

It can be helpful to think of delays in a green-yellow-red paradigm:

  • Very few delays at a provider or overall (Green): You’re currently sending email within your approved range for your sender reputation, but if you suddenly send a lot more email than is typical for you, you might run into trouble.
  • A significant number of delays at a provider or overall (Yellow): Your send is being delayed by one or more mailbox providers, but after some delays, your email is being delivered. This is common if your sender reputation is just getting established, or if you’re sending more volume than is typical for you.

Looking at the reasons for delay at the bottom of the Bounce/Delay metrics screen, if you see explanations like “Throttled – try again later” or “you have recently hit the rate limit”, this is a sign that you’ve either sent too quickly or too much volume to that mailbox provider.

Some of the reasons given by the Mailbox Provider for why they delayed delivering our email.
Some of the reasons given by the Mailbox Provider for why they delayed delivering our email.

You can send more slowly next time by using the Max emails per second feature on the Targeting screen of your mailing. ActionKit supports sending as slowly as 2 emails per second, which would trickle out a Mailing to 10,000 people in a little under 1.5 hours.

Emails Per SecondTargeting SizeTime Required
210,000~1.5 hours
1010,000~15 minutes
10100,000~2.75 hours
1001,000,000~2.75 hours
Knowing how quickly your mailing will finish sending can help you decide the right level of rate limiting.

There’s no hard and fast rule on how quickly or slowly to send — it’s a balance between how timely your mailing is, when you’re starting your send, and your users’ typical patterns of expecting email from you. For Mailings with very small targeting sets, going slowly typically isn’t a problem.

If you have a lot of recipients, you may need to send more quickly. For example, if you had a Mailing targeted to 1 million people, sending at 2 emails per second would take almost 6 days — and many of those emails would be delivered while recipients were asleep. That’s an extreme example of going too slowly to be timely or effective.

You can view your actual observed sending speed on the Mailing Report screen (search for “messages per second” to see your Mailing’s observed send speed). For example, if your sending speed was 1000 messages per second and you’re seeing delays telling you “you have recently hit the rate limit”, that’s a clear sign to slow down your next send. You can experiment with your next send to see whether going more slowly results in fewer delays. If so, you can either try to add a little speed next time or keep steady. If going more slowly doesn’t result in fewer delays, you may need to go more slowly still, or may be sending too much volume.

Generally speaking, it’s better for your sender reputation to use ActionKit’s rate limiting to slow down your sends than to have the mailbox provider slow your sends down themselves.

One common pitfall to avoid is if you segment all of your traffic with a given mailbox provider that you’re having a problem with out to its own separate mailing, you may need to rate limit your send to send much more slowly than if your targeting were mixed with other mailbox providers. This is especially tricky to get right, so we don’t often recommend it unless you’re very careful.

It’s important to remember that speed is only one component — volume is another. If you are sending more email than is typical for you, going slowly may not help you as much.

  • Large number of delays at a provider or overall (Red): Your send is being delayed by one or more mailbox providers and your email may not be delivered, or may be delivered to the spambox. This is common if you saw a significant number of delays previously for a while but didn’t course-correct, or are sending a lot more volume than is typical for you. This can also happen during warmups. When this happens not during a warmup, you’ll often need to ask for a reputation reset in order to get your email flowing again with this provider.

When a large number of delays occur at a particular mailbox provider, they may delay your emails or block you from sending altogether. This may show up as the delay reason “Sending IP temporarily suspended” or similar. Such blocks are typically temporary, but if you are blocked repeatedly without making any changes, you’re likely to receive a permanent block that will require working with the mailbox provider to correct.

Here, we see that Comcast throttled us and eventually blocked our sending IP
Here, we see that Comcast throttled us and eventually blocked our sending IP

It’s important to pay close attention when you’re blocked at a mailbox provider. If you do get blocked temporarily, you can usually fix these problems on your own by limiting your targeting at this provider to a smaller subset than the one that got you in trouble, and sending to your most active users.

These temporary blocks may happen more commonly during the warm-up period when you’re first establishing your sender reputation with a mailbox provider, but they can happen any time a mailbox provider decides you’re sending too much email, too quickly, or to too many users who are uninterested in receiving or interacting with your email.

If you’ve been blocked at a mailbox provider for a while, or can’t get unblocked on your own, you can reach out to ActionKit support. We can work with the mailbox provider in question to get you unblocked, though they’ll often recommend going more slowly and sending to your most active users for a while.

Don’t let recurring donors lapse!

Recurring donors are often your most committed supporters — so it’s especially important not to let them lapse.

ActionKit comes standard with about 300 built-in reports, including a few that can help you identify donors whose cards are about to expire and whose cards recently failed.

These reports are meant to be used for targeting recurring mailings, allowing you to automate the process of checking up on donors.

First, create your mailing

The first step here is to compose a mailing that briefly tells donors their cards are about to expire, how much you appreciate them, and how they can update their credit card so their donations can continue to be processed.

How can they update their credit card? This is where the Update Recurring Donation page type comes in. Either create a page of this type or use the default, and link to it.

This mailing links to the Update your Monthly Donation page

Test it out!

Set up a recurring donation of your own, then send yourself a proof of this mailing using your user ID that has this recurring donation, so you can see exactly what the process will look like to your users.

Sending myself a proof, showing what my mailing will look like, to an email with a recurring donation

Use the built-in targeting

ActionKit’s built-in query “Donors Whose Cards Expire Next Month” is exactly what we need to include on the Target screen. This report finds all subscribers with an active recurring donation whose credit cards are about to expire:

Include the “Donors Whose Cards Expire Next Month” query in your mailing

Make it recurring

Next, on the Proof and Send screen, we’ll need to tell ActionKit we want to make this mailing recurring, which will allow us to set it and forget it.

At the bottom of the proof and send screen is an option to make this mailing recurring:

When we make this mailing recurring, we can set it and forget it

Next, we’ll either choose an existing recurring mailing series or create a new one. For this example, I’ll create a new one:

Creating a new recurring mailing series

In this example, the recurring mailing series only emails once per month. But other recurring mailing series can email much more frequently. Some are even configured to send every hour. If you’re using a recurring mailing series that can potentially send frequently, be sure to configure its targeting to exclude those who already received the mailing recently. Use the People who have recently received a recurring mailing series:

This will exclude anyone who has received recurring series #1 within the last 30 days

You’ll need to look up the recurring series ID in order to know what to put for “Recurring Schedule ID”. WHERE?

Most of the time, you’ll want to exclude all sends of the series you’re working on, but if you want to exclude anyone who has received any recurring series at all, you can use Recurring Schedule ID 0.

Try it out!

The example above shows how to set this up for cards that are about to expire. ActionKit also includes a built-in report for cards that have recently failed. Using this blog post, try to set up a recurring mailing for recently failed cards, too!

Feature Spotlight: Faster mailing builds with summary_user

One of the most common types of support requests we get is about how to make your mailings build faster.

One common root problem of slow mailing builds is often that the underlying reports themselves are slow. Using caching when appropriate can often help, but the biggest wins come from improving the reports themselves.

Maybe you’re using some reports like these in your mailing targeting:

  • When did the user last receive a mailing?
  • When was the user’s last open?
  • When was the user’s last click?
  • When was the user’s last action?
  • When was the user’s last donation?
  • How many actions has this user taken in the last 30 days?

These are common reports, and they’re great questions to ask about your users! They’re great ways of measuring engagement and figuring out who your most committed supporters are.

Unfortunately, these reports can often be pretty slow, too.

And if you’re using slow query reports in your mailings, your mailings are going to take a long time to build their targeting, which means it takes longer to get proofs or get your mailings out the door.

Why it’s slow

The most common reason these reports (and therefore the mailing builds) are slow is these reports are looking through large database tables with millions or hundreds of millions of records. And calculating those results can take a lot of time!

Some of the slowest tables to run reports on include:

  • core_action (all actions ever taken by users)
  • core_open (all mailings ever opened by users)
  • core_usermailing (all mailings ever received by users)

In fact, that’s exactly why we created the summary_user table, which has all of the data you’re commonly looking for in these types of engagement queries, like:

  • When did this user last take action?
  • When did this user last take action from a mailing?
  • When did they last open a mailing?
  • When did they last click a mailing?
  • When were they last subscribed to the default mailing list?
  • When was their last donation?
  • When did we email them last?
  • How many actions have they taken in the last 30 days? 60? 90? 180? 270? 365?

Why this matters

Since we don’t have to look through the entire history of actions and donations and mailings and opens and clicks and so on, every single time, for every single user — because we do all that heavy lifting behind the scenes and keep summary_user regularly up to date, your reports will run SO fast and your mailings will build SO much more quickly.

In my tests, I found that smaller clients will see a speedup of 400X faster mailing builds when using summary_user compared to calculating the same results on other (slow) tables.

For larger clients, the benefits are even greater: we’re talking 3000X faster. So a report that you might have been waiting several minutes or even up to 30 minutes to complete, now completes in seconds when using summary_user.

Here’s how

To get started, you’ll need to edit your query reports to use the summary_user table whenever possible. This will require some custom SQL, but the good news is your queries will be much more straightforward, easier to read and understand, and of course, faster.

Here is an example of some code generated by the point-and-click query builder to calculate the number of actions a user has taken in the last 90 days:

Before: a slow query to calculate actions taken by a user in the last 90 days

If you look closely, you’ll notice that this query joins to the core_action table, which is large and therefore can be pretty slow.

This next bit of SQL code does the exact same thing, but has been rewritten to use the summary_user table. Notice that it’s much more straightforward and easy to read — and of course, it’s much faster too:

After: a fast query using summary_user to show actions taken by a user in the last 90 days

Refer to the database reference on summary_user to get started on transforming your queries.

For best results, start with optimizing a query that is very slow, or a query that is used very frequently in your targeting: go for the biggest, easiest wins first.

But summary_user doesn’t have _________!

Now if you’re thinking “this sounds great, but summary_user doesn’t have this particular stat we really care about” — custom user fields and user updaters are here for you.

These allow you to store whatever information you like about your users in custom user fields (like for instance: how much money did this user give in calendar year 2020?) and keep them up to date with user updaters.

Check out a video version of this blog post, plus our feature spotlight blog post and videos on custom user fields and user updaters for more about how to get started using these powerful features to speed up your mailing builds even more!

Feature Spotlight: Custom User Fields

Custom user fields are a very commonly-used feature in ActionKit. Many clients use them to store information like a user’s employer or occupation, but there are SO many different bits of information that could be useful to store!

In this blog post, we’ll give you a few ideas of things you can do with custom user fields, but what you do with it is completely up to you!

Why should I use custom user fields?

Beyond storing useful data like a user’s employer or occupation, lots of clients like to run reports on historical data, like “how much money did this user given in 2020?” “How much did they give in 2018? 2016?”

Unless someone has a time machine, historical data like that doesn’t change very often. The amount someone gave in 2016 is fixed. But calculating that information from the database — depending on what data you’re retrieving, how far back you’re going, how many users you have, and a few other factors — this can be VERY slow!

Lots of clients also like to us merge queries to calculate suggested ask snippets based on historical donation data including a user’s highest previous contributions, but there are so many ways to calculate suggested asks!

Still, if you’re often using merge queries in your mailings, and you find those merge queries are very slow, you might want to use custom user fields to make your mailings build much more quickly.

Some common reasons your reports, mailing builds, and merge queries might be slow include:

  • Your report / merge query looks at large database tables including millions or hundreds of millions of entries
  • Your report / merge query could benefit from caching or optimization
  • Your report / merge query performs time-consuming calculations on several years of historical data

And when you’re targeting your mailings to hundreds of thousands or millions of people, and doing these calculations each time for every single recipient, that can slow things down even further.

Don’t forget summary_user

For many common situations, we already have fields that you can use — you don’t need to create a custom user field to calculate information like:

  • When did a user last take action?
  • When did a user last take action from a mailing?
  • When did a user last receive a mailing?
  • When did a user last open a mailing?
  • When did a user last click a mailing?
  • When did a user last donate?
  • When was a user last subscribed to the main email list?
  • How many actions did a user take in the last 30 days? 60? 90? 180? 270? 365?

For these questions, see the summary_user table, where we’ve collected these stats and keep them updated.

One way to think about custom user fields is as a supplement to summary_user!

Why this matters

Using custom user fields, your mailing builds will complete MUCH more quickly than if you were doing these queries on the fly.

You can also use custom user fields as snippets available in your pages and your mailings.

Don’t forget — you can target your mailings based on your custom user field data.

Some example ideas

Here are a few example ideas for custom user fields that you could do:

  • Count of donations made in 2020
  • Amount of donations made in 2020
  • Largest one-time donation ever made
  • Amount a user can give before they “max out” (for political parties and candidates)
  • Propensity scores

How to get started

You can of course have your users enter data into custom user fields on forms like surveys and petitions. But to add data in bulk, read on.

First, create a custom user field that will store the information you want to capture. In this example, we’ll use a field called donation_count_2020 to store the number of donations a user made in calendar year 2020.

Next, create a report that calculates the value of what that custom user field should be for each user.

This report calculates the number of donations a user made in calendar year 2020

Notice that the name of the column where we’re calculating the number of donations a user made in 2020 is “user_donation_count_2020” — this is important, as it must match the name of the custom user field we created above, with the “user_” prefix.

The first column here is the user ID, which will be important later when we upload the file.

Then, run your report and view the results. When the results look correct to you, download it as a CSV (comma separated values) file.

Next, create an import page. (As a general rule, when importing custom user fields, I’d make sure the import page was set to not change the subscription status of the users you upload)

Next, upload your file, being sure to check the box that says “Skip Action Creation”. This will make your upload go much faster — though it only works when you’re only uploading custom user fields, which we are here.

When the upload completes, all of the users you imported will have the number of donations they made in 2020 stored in the custom user field donations_count_2020!

Although it may seem strange to upload data from ActionKit back into ActionKit, this is a great way to set up custom user fields — and best of all, take advantage of big speed improvements by not needing to calculate the values every time.

But how do I keep user data up to date?

You’re probably thinking “This is nice, but it’ll never work for us, because I’m not doing a manual import every day to keep this information up to date!”

And you shouldn’t have to! That’s time-consuming, easy to forget or miss, and error-prone. Much better to do it automatically!

This is where user updaters come in. User updaters are a new feature that’s specifically designed to help you keep your custom user fields up to date on a regular schedule. You’ll make a report similar to the one we made above, then set it to run on a schedule. We’ll update your users’ custom fields on a regular basis and you don’t have to think about it ever again!

Give this a try — and be sure and let us know via support how you’re using custom user fields! We love to know all of the creative ways that you’re using ActionKit.

Also be sure to check out a video version of this blog post, plus our feature spotlight blog posts and videos on summary_user and user updaters for more!

Feature Spotlight: User Updaters

First things first: if you haven’t read our feature spotlight on custom user fields, do that before reading this one!

Custom user fields are powerful, but they’re not much use if the data in them is out of date.

For some custom user fields, they don’t need to be updated regularly. Historical data, like the amount of money a user gave in calendar year 2020, isn’t going to change — it’s over and done. You can import that once and be done.

But if you’re tracking information like “how much money has a user given in this current calendar year?”, you’ll want to keep that information regularly up to date.

Sure, you could do a manual import process every day to update that information manually, but it’s easy to forget, or not have time to do it. Better to automate these types of tedious, time-consuming, error-prone processes.

This is exactly why we created user updaters.

User updaters run the custom user field import for you, using the exact same report you made for your initial custom user field import, and we run them on a schedule that you set.

To get started, first create a report for your custom user field import. Or, if you already created one for your initial import, re-use it!

Next, ensure that your report’s column names match the custom user fields, just like we did in the custom user fields feature spotlight.

Also be sure that you’re only including relevant columns in your user updater report. This means one column to identify your user, like user ID or email, and your custom user field columns.

Here’s an example: lots of clients (mainly political parties and candidates) want to know how much money a user can give before they “max out”. Sure, you could calculate that manually and use it in a merge query, but that could make your mailing take a long time to build.

With a user updater, this information stays up to date behind the scenes, and your mailings build lightning fast.

The User Updater Maxout 2021 report, calculating how much money a person can give before they “max out” for this cycle

Notice that we have two columns: one for the user ID and another titled user_maxout_amount_2021. If we haven’t yet created a custom user field with the name maxout_amount_2021, we’ll want to do that before continuing any further.

Next, give your report the updater report category and save.

When your report finishes running, confirm that the results look good to you, spot-checking several users to ensure the results.

Next, create your User Updater. From the Users tab, find User Updaters in the sidebar, then create one. You can run user updaters manually, or on a schedule as you prefer.

This user updater runs on a daily schedule

In the screenshot above, I’ve given my user updater a helpful name and description, and I’ve set myself to receive email updates about whether the updater succeeded or failed on each of its runs.

The Query Report is the actual report that runs (and is imported); you’ll only see reports that have the updater category here, and each query report can only be associated with a single updater.

You can run your updaters on a daily, weekly, or monthly schedule as you prefer, or remove the schedule once you no longer need to update the field. For example, once it’s 2022, I won’t need to update the above field anymore, so I can turn off the schedule.

User Updaters will also tell you the last time they ran, whether it succeeded, which columns it updated, and how many users were updated as part of the run:

Results of the last user updater run: 3 users updated

Keep in mind, user updaters are only used to update custom user fields and user groups!

Check out a video version of this blog post, plus our feature spotlight blog posts and videos on custom user fields and user groups for more great tips!

Feature Spotlight: User Groups

If you’ve read my blog post A Tagging System That Works or seen any of my presentations over the years, you know I love tags! They’re such a powerful feature for categorizing your users, targeting your mailings to them, and building reporting about them.

But over the years, lots of clients have shared feedback about the ways that tags don’t meet all of your needs.

We’ve taken your feedback and created a new system that complements tags, called user groups.

Before we go too deep into what user groups are, let’s talk tags first.

It’s important to remember that you apply tags to pages, not directly to users. Then, when a user takes action on that page, they gain that tag.

One great thing about tags is they’re applied retroactively, meaning if you change a page’s tags, we’ll update the user’s tags automatically as a result.

Where tags fall short

Over the years, you’ve asked us questions like “Can I add a user directly to a tag?” and “Can I remove a user from this tag?”

And while there ARE ways to do these, they’re not straightforward.

You could, for instance, set up an import page, give the import page the tag you wanted, and import a user to add them to a tag. But that’s a lot of work, and probably too much trouble for a single or even a few users.

But removing users from a tag is even more trouble. You’d have to either delete all of the actions that user has taken on pages with that tag, or remove the tag from all of those pages. But then you’re deleting actions, which you probably don’t want to do, or you’re removing those tags from lots of users, which again, you probably don’t want to do.

And this is exactly why we made user groups: so you could add users directly to a group and remove them directly from a group without any side effects.

Like tags, if a user takes action on a page with groups, they will be added to that group. But unlike tags, if you change a page’s group, we DO NOT retroactively go back and update your user’s group memberships.

This isn’t a technical limitation — we could in theory — but since you can remove users from groups manually, we wanted to minimize the chance of automatically adding a user to a group you’ve already removed them from. So we don’t retroactively update group membership when you change a page’s user groups. But for action takers going forward, they will get the new groups.

Another way to understand tags versus groups is to look at the ways a user can gain or lose a tag versus a group:

How a user gains a tag:

  1. Taking action on a page with those tags

How a user is added to a group:

  1. Taking action on a page with those groups
  2. On that user’s Change User overview screen
  3. From an import (using the group or group_id columns)
  4. From a user updater (using the group or group_id columns)
  5. From the REST API

How a user loses a tag:

  1. Deleting this user’s actions on all pages with those tags
  2. Removing those pages’ tags

But these a probably not worth the side effects! I don’t recommend this — instead, groups are probably more appropriate here!

How a user is removed from a group:

  1. On that user’s Change User overview screen
  2. From an import (using the group_remove or group_id_remove columns)
  3. From a user updater (using the group_remove or group_id_remove columns)
  4. From the REST API

Like tags, you can also target your mailings based on user groups, and you can also run reports to analyze performance on user groups.

To get started using user groups, you can either create user groups ahead of time from either the Pages tab > Other > User Groups or from the Users tab > Manage Groups, or you can create them on the fly from the Action Basics screen of your page.

Adding user groups from the Action Basics screen. Groups don’t replace tags – they’re a supplement!

And of course, you can add tags on the user overview screen for any user.

Adding users directly to a group from the user overview screen

Thanks again for providing great feedback on ActionKit — what’s working and not — and telling us all the ways you’re using ActionKit. We’d love to hear about how you’re using groups!

Be sure to check out a video version of this blog post, plus our feature spotlight video and blog post on user updaters for more!

10 More Features Every Client Should Use

At ClientCon 2020, I ran a presentation called “10 More Features Every Client Should Use,” intended to help clients get the most out of ActionKit.

This is the second in the series, continuing from “10 Features Every Client Should Use” I originally ran in 2019.

In both of these presentations, I wanted to highlight a handful of different features that every client would find useful and wanted it to be a good mix — some things quick and easy, others that would take a little more time to set up fully. Here’s a brief overview:

Tag your Pages and Mailings

Tagging your pages and mailings allows you to create robust reporting on the performance of your pages and mailings by category. Tagging is especially useful when using prefixes, like topic-immigration instead of just immigration, as this allows you to group similar tags together.

It’s also never too late to go back and tag old pages and mailings! Not only will your page tags be applied to action takers retroactively, but our advanced search and bulk edit features make tagging old pages and mailings a quick job.


Setting up a re-engagement process is one of the best ways to boost your open, click, and action rates — as well as your deliverability.

Avoid getting pushed into the spam folder or promotions tab by only sending to your most engaged supporters — and letting the old email addresses go.

New ActBlue Sync

A few long-time ActionKit clients are still using the legacy ActBlue sync, which has a few problems: it erroneously treats recurring donations as multiple one-time donations, refunds don’t show up correctly, and sync failures aren’t recorded.

We built our own ActBlue sync to solve these problems, and almost everyone has happily switched over.

If you’re still using the legacy ActBlue sync, file a support ticket and ask about moving over to the new ActBlue sync!

Always use HTTPS

Web browsers will display warnings in the URL bar for sites that are not using HTTPS. This can cause your visitors to pause and ask themselves “What does it mean that this site isn’t secure? Should I not sign this petition? Does this mean I shouldn’t make a donation?”

We can turn on the “Always use HTTPS” feature for you to prevent these types of warnings, but before we do, you’ll need to make sure all of your images, CSS, Javascript, and any other assets are being loaded using HTTPS, not HTTP.

Once you’ve made these updates in your templatesets, we can flip the switch on our end. Just open up a support ticket and we’ll do the rest!

Review Staff Access

It’s always a good idea to periodically review staff accounts that have access to your ActionKit (or any other system, really) and disable the ones you aren’t using anymore.

The Staff query type in the Query Builder can help you make a quick report of your staff users, who has what access, and when they’ve last logged in.

Just be careful not to disable admin (that’s us!), or any other users that are used by your integrations like ActBlue.

Custom Page Fields

Custom page fields allow you to make big and small changes to your pages without needing a lot of ongoing code changes. This year, we focused on how to add custom Javascript code on a one-off basis.

Timed Sends

Timed sends allow you to deliver mailing to a user in their specific time zone. In other words, if you’ve found that 10:00 am is the best time to send for your users, you can make sure they receive your mailing at 10:00 am — no matter where they live.

Custom User Fields

Custom User Fields allow you to store information about a user like their employer, occupation, membership level, and so much more.

You can also target your mailings based on what’s stored in these custom fields, and we’ve added a new feature to imports that allow you to import data into custom user fields lightning fast.

Cross-site prefill

Cross-site prefill uses a cross-client shared pool of user profiles in order to pre-fill known user data into your form and boost action rates. This is similar to, but different than user recognition based on AKID.

Stop Spam with Recaptcha Challenges

ActionKit has built-in protection against spam bots, but if you find that spammers are still getting through, you can add a Recaptcha challenge to your page.

It’s also possible to configure Recaptcha site-wide and use a custom page field to disable these on a one-off basis for your pages if needed.

To learn more about setting these up, check out the video 10 More Features Every Client Should Use — and file a support ticket if you have any questions or have difficulty setting these up!

How to set up AMP for Email

Ever want to send a survey that you can fill out in an email? Now you can!

AMP for Email (Accelerated Mobile Pages for Email) is a new feature that allows you to do just that. In select email clients (mostly Google, which created AMP, and others who are adopting it), you can add forms and other similar web-like dynamic elements within your emails themselves.

And if your user’s email client doesn’t support AMP? They’ll receive the HTML version of your email instead.

In other words, AMP is NOT meant to replace your current emails. It’s there to supplement them!

Setting up AMP takes a bit of work and has a learning curve, but we’re here to help. Here’s how to get started.

Before you can use ActionKit forms in your AMP emails, you need to add as an Allowed Origin under CORS Settings on the Configuration screen. (If you forget to add this as an Allowed Origin, actions will be processed but the form success message won’t display to your users, making it seem like your form did not work.)

You can begin using AMP in your mailings by using any AMP-compatible Email Wrapper. We’ve provided an AMP-compatible Email Wrapper for you (AMP Template with Sidebar), but you can also create your own. Once you’ve chosen a suitable Email Wrapper, the AMP HTML Body field will automatically appear on the Compose screen of your mailing.

It’s important to note that AMP is non-standard HTML. Some elements like img have a direct replacement (amp-img), other elements aren’t supported at all in AMP. There are a large number of features in standard HTML/CSS that are not supported in AMP.

To help you write AMP-compliant email, we have a validator that checks your code for compliance as you go. If the validator finds any tags, attributes, or other code that doesn’t pass Google’s requirements, we’ll issue a warning to help you correct the code. Sometimes the edits you need to make might be in your AMP HTML Body, other times you may need to edit your email wrapper in order to fix the validation error.

To make things even easier, we’ve provided an example form and highlighted some common issues in our documentation.

While you’re testing, you can send yourself AMP-enabled emails if you enable a setting in your email address’s Gmail (or equivalent) account.

In order to send yourself AMP emails, open your Gmail settings. Under General, go to Dynamic Email:

General Settings in Gmail

Make sure Enable dynamic email is checked, then click on Developer settings and enter your sender email to always allow dynamic emails from this sender, like this:

Preview dynamic emails during development

That will work to send yourself test AMP emails, but before you can send AMP emails to your supporters, you’ll need to first register with Google. You’ll need to do this once per sender email address (e.g. the email part of this from line: “Shannon Turner” <>). This process involves sending a production-quality (non-test) AMP email to Google, and completing a short Google form.

When we registered with Google, we used the following AMP HTML Body when sending our working, production-quality email:

<form class="ak-form" method="POST" action-xhr="" accept-charset="utf-8">
    <input type="hidden" name="page" value="what-trainings-would-you-like-next">
    <input type="hidden" name="response_type" value="json">
    <input type="hidden" name="email" value="{{ }}">
    <input type="hidden" name="source" value="mailing">
    <input type="hidden" name="mailing_id" value="{{ mailing_id }}">
    <div class="ak-grid-row">
        <div class="ak-grid-col ak-grid-col-12-of-12">

            <div class="ak-mobile-padding ak-text-expander">
                <p>{{ user.first_name|default:"ActionKitties"|title }},</p>
                <p>We've run a ton of trainings over the years -- some highlights include:</p>
<li><a href="">ActionKit 101</a></li>
<li><a href="">Advocacy 101</a></li>
<li><a href="">Fundraising 101</a> </li>
<li><a href="">Mailing Wrappers &amp; Template Blocks</a></li>
<li><a href="">Building Dashboards</a></li>
<li><a href="">Intro to the Query Builder</a></li>
<li><a href="">Intermediate Mailings</a></li>
                <p>But we're curious: what topics would you like to see covered in the next training?</p>
                    <p><b>Complete the ActionKit survey in this email below to let us know -- you can submit the survey right from this email!</b></p>


    <div class="ak-grid-row">
        <div class="ak-grid-col ak-grid-col-4-of-12">
            <div id="survey-contact" class="ak-styled-fields ak-labels-overlaid ak-errs-below">
                <ul class="compact" id="ak-errors"></ul>




        <div id="ak-survey-questions" class="ak-grid-col ak-grid-col-8-of-12">
            <div class="ak-field-box ak-field-box-padded ak-styled-fields ak-labels-above ak-errs-below">

                    <label class="ak-survey-question-label">
                        <h3>                        What level of complexity would you like to see more trainings on?</h3>
                    <div class="checkbox-item ak-survey-checkbox-set ak-input-set"><label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_complexity" id="id_action_action_training_complexity_1" value="1"> Beginner-friendly, please. These trainings are especially helpful for onboarding new staff.</label><br>  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_complexity" id="id_action_action_training_complexity_2" value="2"> Intermediate. Beginner-level trainings are already recorded and we&#39;re eager to dig deeper.</label><br>  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_complexity" id="id_action_action_training_complexity_3" value="3"> Advanced. The intermediate level trainings aren&#39;t advanced enough for me!</label> </div>
                    <label class="ak-survey-question-label">
                        <h3>                        Broadly, what areas would you like to see more trainings on?</h3>
                    <div class="checkbox-item ak-survey-checkbox-set ak-input-set">
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_pages" value="Pages"> Pages</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_targets" value="Targets"> Targets</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_templatesets" value="Templatesets"> Templatesets</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_custom_page_fields" value="Custom Page Fields"> Custom Page Fields</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_a_b_page_tests" value="A/B Page Tests"> A/B Page Tests</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_delivery" value="Delivery"> Delivery</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_suggested_asks" value="Suggested Asks"> Suggested Asks</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_tags" value="Tags"> Tags</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_spam_prevention" value="Spam Prevention"> Spam Prevention</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_events" value="Events"> Events</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_custom_event_emails" value="Custom Event Emails"> Custom Event Emails</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_mailings" value="Mailings"> Mailings</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_custom_mailing_fields" value="Custom Mailing Fields"> Custom Mailing Fields</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_email_wrappers" value="Email Wrappers"> Email Wrappers</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_custom_email_wrapper_fields" value="Custom Email Wrapper Fields"> Custom Email Wrapper Fields</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_merge_files" value="Merge Files"> Merge Files</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_merge_data" value="Merge Data"> Merge Data</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_intermediate_snippets" value="Intermediate Snippets"> Intermediate Snippets</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_advanced_snippets" value="Advanced Snippets"> Advanced Snippets</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_re-engagement" value="Re-engagement"> Re-engagement</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_pre-flight_mailing_dashboard" value="Pre-flight mailing dashboard"> Pre-flight mailing dashboard</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_reports" value="Reports"> Reports</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_building_dashboards" value="Building dashboards"> Building dashboards</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_query_templates" value="Query templates"> Query templates</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_users" value="Users"> Users</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_custom_user_fields" value="Custom User Fields"> Custom User Fields</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_advanced_features" value="Advanced Features"> Advanced Features</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_salesforce_sync" value="Salesforce sync"> Salesforce sync</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_everyaction_sync" value="Everyaction sync"> Everyaction sync</label><br>
  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_topics" id="id_action_action_training_topics_not_sure" value="Not sure"> Not sure</label><br>
                    <label class="ak-survey-question-label">
                        <h3>                        Are there other resources you want to see more of?</h3>
                    <div class="checkbox-item ak-survey-checkbox-set ak-input-set"><label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_other_resources" id="id_action_action_training_other_resources_documentation_-_the_campaigner_s_guide_is_very_helpful" value="Documentation - the campaigner&#39;s guide is very helpful"> Documentation - the campaigner&#39;s guide is very helpful</label><br>  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_other_resources" id="id_action_action_training_other_resources_documentation_-_the_developer_s_guide_is_very_helpful" value="Documentation - the developer&#39;s guide is very helpful"> Documentation - the developer&#39;s guide is very helpful</label><br>  <label class="ak-survey-checkbox-choice"><input type="checkbox" class="ak-survey-input" name="action_action_training_other_resources" id="id_action_action_training_other_resources_blog_posts_tutorials_and_how-to_guides" value="Blog posts, tutorials, and how-to guides"> Blog posts, tutorials, and how-to guides</label><br> </div>

                    <label class="ak-survey-question-label">
                        <h3>                        Specifically, what would you like us to do more trainings on?</h3>
                    <textarea class="ak-survey-input" name="action_action_training_freeform" id="id_action_action_training_freeform" rows="4" style="height:5.0em; width: 80%;" ></textarea>

                    <label class="ak-survey-question-label">
                        <h3>                        Anything else you want to share?</h3>
                    <textarea class="ak-survey-input" name="action_action_training_anythingelse" id="id_action_action_training_anythingelse" rows="4" style="height:5.0em; width: 80%;" ></textarea>

                <button type="submit" class="ak-submit-button" value="Submit Survey" style="border-radius: 16px; background-color: #dd0000; display: inline-block; padding: 0 22px; margin-bottom: 10px; line-height: 200%; height: 32px; color: #fff; font-size: 16px; font-weight: bold; text-transform: uppercase; font-family: Helvetica, Arial, sans-serif; text-align: center; text-decoration: none;">Submit Survey</button>

                <div submit-success>
                  <template type="amp-mustache">
                    Your survey responses have been recorded! Thanks for letting us know what you'd like to see!
                <div submit-error>
                  <template type="amp-mustache">
                    Hmm, something went wrong and your survey response didn't go through.



You can modify the above to meet your needs, but hopefully this helps get you started.

While testing, don’t forget that any proofs you get WILL RESULT IN AN ACTION BEING TAKEN IF YOU SUBMIT THE FORM, just like if you were to submit a form after clicking a non-AMP email proof.

If you have trouble setting up your AMP email, consult the AMP for Email specification. If you’re still stuck, file a support ticket!

Looking forward to seeing what you come up with!

More ways to provide suggested ask snippets

In Fundraising in ActionKit? Don’t forget these tips! we showed how you can use suggested ask rules to show personalized donation suggestions.

But that’s not the only way to do this! Lots of clever clients have developed other ways to show personalized suggestions, and those are worth a mention here too.

Many of these tips are explained in detail in our Intermediate Mailings training, which you may find useful!

Some clients like to use the {{ donations.highest_previous }} snippet in their mailings, along with the |multiply filter in order to show different potential giving levels.

Assuming someone has given previously, the {{ donations.highest_previous }} snippet will show the highest one-time donation they’ve given before.

When to use requires_value

To restrict your mailing to ONLY those who have given previously, use the {% requires_value donations.highest_previous %} snippet. If you use this, you’ll also want to adjust your targeting to make sure your mailing only goes to previous one-time donors.

But you don’t have to use the {% requires_value donations.highest_previous %} snippet. In fact, there’s a good argument to be made that even if someone hasn’t given before, you still want to make an ask! Suggested ask rules do a good job of covering this situation, but this post is all about other ways of approaching the same problem. In this case, you’ll want to remove the {% requires_value donations.highest_previous %} snippet from your mailing.

Adding donation levels

Using the |multiply filter, we can show a higher (or lower) amount than the user’s highest previous one-time donation.

For example, {{ donations.highest_previous|multiply:1.5 }} will multiply a user’s highest previous one-time gift by 1.5. If someone’s highest gift before was $10, this snippet will show $15.

You can use as many of these different levels as you like in your mailings, to offer a set of choices. Use the amount={{ donations.highest_previous|multiply:1.5 }} and prefill=1 URL parameters when creating links in your mailings.

Get lots of previews and proofs

Let’s say we have a user whose highest previous one-time gift was $10, and we want to show them a multiple of 1.25 to ask them for $12.50.

Using the {{ donations.highest_previous|multiply:1.25 }} snippet looks wrong though: instead of $12.50, we see $12.5 in the preview.

Getting lots of previews and proofs is so important — it’s the only way you’ll be able to notice these sorts of oddities.

To fix this so you can properly display cents even when the last digit is a zero, use the |floatformat:2 filter. This tells ActionKit “I expect this to be a ‘floating point number’ (also known as a decimal number), so always round it to two digits.”

You’ll want to apply this to all of your donation snippets that use |multiply, even if you don’t notice problems with them. (Depending on the initial values and how you’re multiplying, you might see problems, or you might not).

So you’ll end up with: {{ donations.highest_previous|multiply:1.25|floatformat:2 }} – it’s important that the floatformat comes last (is the rightmost filter), because otherwise it may not do anything.

Re-using variables

Behind the scenes, ActionKit does a database calculation every time you use the {{ donations.highest_previous }} snippet (and some other snippets, too). That’s fine, but if you use that snippet more than a few times in your mailing, you might want to switch to another way of using it, or your mailing send speed might be slower than it needs to be.

Using the {% with %} tag, we can assign the value of {{ donations.highest_previous }} to a variable. In these examples, let’s assign them to the hpc variable.

First, we assign the variable using the tag {% with donations.highest_previous as hpc %} and then at the end of the email, we’ll use {% endwith %} to tell ActionKit we don’t need this anymore.

This also has the added benefit that we don’t need to type {{ donations.highest_previous }} over and over again; we can instead use {{ hpc }} to mean the same thing.

Now we can use our filters on the hpc variable in the same way as before, like {{ hpc|multiply:1.25|floatformat:2 }}.

Rounding to nearest $5 / nearest $10

Using some math tricks, it’s also possible to round to the nearest $5 or nearest $10 if we don’t care about cents.

To round to the nearest $5, use {{ hpc|multiply:0.2|floatformat:0|multiply:5 }}. This uses some math tricks and rounding (notice the floatformat filter is in the center, not at the very end as usual) to get the value we’re looking for.

To round to the nearest $10, use {{ hpc|multiply:0.1|floatformat:0|multiply:10 }}.

It’s also possible to use these alongside other multiplication levels, like an HPC x 1.5, rounded to the nearest $10: {{ hpc|multiply:1.5|multiply:0.1|floatformat:0|multiply:10 }}.

There’s lots more tricks you can use to ask for different donation amounts from your users — whether you’re using suggested ask rules or not, ActionKit has lots of ways to personalize your mailings!