Skip to content
Glassjaw
Data & personalisation 7 min read

Next best action instead of another campaign

A practical route from a campaign calendar to next best action: defining the action set, separating scoring from arbitration, and starting with rules before models.

Abstract cover art: clustered nodes joined by edges on a dark blue field

On a Tuesday in October, one customer qualifies for four things at once. She is in the replenishment audience because her last order was six weeks ago. She is in the loyalty tier push because she is forty points from silver. She is in the category newsletter, and she abandoned a basket on Sunday.

Four teams built four good campaigns. She receives three of them, in an order decided by nothing more than the send times people happened to pick, and unsubscribes from all of it by Thursday.

Nobody made a bad decision. There was simply no place in the system where the decision got made at all. That gap is what next best action exists to fill, and it is a change to how a programme is organised long before it is a change to the modelling stack.

The calendar competes with itself

A campaign calendar assigns time slots to messages. Each owner defends their slot, each slot has a target, and the customer receives the union of everything they qualify for.

The symptoms are familiar. Unsubscribe rates that rise with tenure rather than falling. High-value customers receiving more contact than anyone, because they qualify for more audiences. Two messages contradicting each other, such as a price promotion arriving the day after a loyalty benefit.

Calendar planning cannot fix this, because the conflict happens at the individual level and the calendar operates at the campaign level. Adding a fifth campaign with better targeting makes it worse.

The alternative inverts the unit of planning. Instead of asking which customers go into this campaign, you ask which action is best for this customer today, from everything currently available.

Define the action set before you touch a model

The most common failure is starting with the algorithm. Teams commission a model, then discover that there is nothing for it to choose between, because the actions were never defined as comparable objects.

An action is an offer, a piece of content or a prompt, with everything needed to decide about it attached:

  • The eligibility rule, expressed as a condition on the customer record.
  • The channels it can run in, and the minimum quality of address required.
  • A value: the expected commercial outcome if the customer takes it, in money.
  • A validity window, after which the action expires and leaves the pool.
  • A priority band for cases where value alone is a poor guide, such as service or regulatory messages.

Ten to thirty actions is a workable starting set for most programmes. Fewer than ten and the decision is trivial. More than thirty in the first quarter and nobody can explain any individual output.

The value field causes the most argument, and it should. Agreeing that a replenishment prompt is worth more than a newsletter click forces the commercial conversation that the calendar has been avoiding for years. Put a finance person in that room.

Scoring and arbitration are two different jobs

These get conflated constantly, and separating them makes the system far easier to debug.

Scoring asks how likely this customer is to respond to this action. That is what a propensity model does, and you need one score per action, not one global engagement score. The models you can actually run in-house are usually enough to start.

Arbitration asks which of the scored actions should be sent now, given everything else. It combines propensity with value, then applies constraints: contact limits, channel availability, priority bands, and anything currently suppressed.

A simple arbitration rule takes you a long way. Rank the eligible actions by propensity multiplied by value, drop anything that breaks a constraint, and take the top one. That is a piece of ordinary application logic, not machine learning, and it should live somewhere a marketer can read it.

Keeping them separate pays off when the output looks wrong. A bad recommendation is either a scoring problem or an arbitration problem, and you can tell which within minutes when the two stages log separately.

Start with rules, and let a model take the ties

You do not need every score to come from a model on day one. Rules encode what the business already knows, and they are honest about their own reasoning.

Sequence it like this:

  1. Build the action set and the arbitration layer, with hand-set priorities and values. Ship it.
  2. Run it against last quarter's history offline, and compare its choices with what was actually sent.
  3. Replace hand-set priorities with modelled propensity for the three or four highest-volume actions.
  4. Add a small exploration allowance, so some traffic tries the second-ranked action instead of the first.
  5. Extend to more actions only when the reporting can explain the current ones.

Step four matters more than it looks. A system that always picks the top-ranked action never learns whether the ranking is right, because it stops generating evidence about the alternatives. A multi-armed bandit is the usual way to hold that trade-off, allocating most traffic to the current best action and a small share to the rest.

Keep the exploration share modest and explicit. Somewhere in the low single digits is enough to keep learning without a noticeable cost. Make the figure a setting someone can change, not a property of a model nobody can see into.

Fatigue, eligibility and the override list

Arbitration decides what is best. Constraints decide what is allowed, and they are what stops a decision engine turning into a faster version of the old problem.

Three constraints do most of the work. Frequency capping, applied across all channels at the send layer rather than per programme. A minimum interval between two actions of the same type. And a cooling period after any message a customer ignored repeatedly.

Identity sits underneath all of it. If the same person exists as two profiles, they get two allowances, and the cap silently fails for exactly the customers who shop most often. This is why we treat identity resolution for guest checkout as a prerequisite rather than a later improvement.

You will also need an override list, and it is better to design it than to have it appear as a series of emergency requests. Name the cases where a human decision beats the engine: a product recall, a service failure, a stock position that has to clear this week. Give those actions a priority band above the scored pool, and log every use.

What to do next

Take one week of sends and count, per customer, how many messages each person received and how many they qualified for. The gap between those two numbers is what arbitration would have been deciding.

Then write ten actions in the format above, including the value field, and argue about the values until they are agreed. That argument, not the model, is the part that changes the programme. The optimisation work follows it.

Ready to transform your marketing?

Let's build something great.

By sending this form you agree to our privacy policy.