The Markin ROI Report for Enterprise Growth TeamsRead now
MARKIN

Add next best action to journeys you already run in Braze

Per-customer arbitration written into the canvases your team already operates.

The short answer

Next best action inside Braze means Markin decides which single action each customer should receive, writes that decision onto the profile as an attribute, and lets your existing canvases branch on it. Braze keeps delivery, frequency capping and consent. Markin supplies the choice and reads it against a holdout.

Last reviewed 2026-09-10

Who this applies to, and who it must not reach

Eligible

  • Customers reachable on at least one Braze channel with valid consent.
  • At least two competing actions the business would genuinely be willing to send.
  • A canvas or campaign that can branch on a custom attribute.

Excluded

  • Customers under an active frequency cap or quiet-hours rule. Braze enforces this, not Markin.
  • Transactional and regulatory messages, which must never be arbitrated.
  • Holdout members, who continue to receive the existing programme unchanged.

The minimum data, and where it normally comes from

Data required for this playbook
What is neededUsual source
Profiles, attributes and subscription stateBraze
Message exposure and engagement historyBraze Currents into the warehouse
Revenue, plan and order historyWarehouse or billing system
Product behaviourProduct analytics or event tables
Consent and identity resolutionCDP, where one is in use

Step by step

How the decision runs

  1. 01Your team

    Define the action set

    List the actions that already exist in Braze, plus the ones you would run if you had a reason to. Arbitration is only meaningful when the alternatives are real.

  2. 02Markin

    Estimate expected value per customer per action

    Each candidate action is valued for each customer on expected incremental margin, not on propensity to click.

  3. 03Markin

    Arbitrate to one decision

    One action wins per customer per window, with the losing candidates and the reason recorded so the choice can be audited later.

  4. 04Markin

    Write the decision to the profile

    The chosen action, its reason and its decision ID are written to Braze as custom attributes. Latency is your sync interval.

  5. 05Your stack

    Branch the canvas on the attribute

    Existing canvases add a branch per action. Templates, localisation, send-time optimisation and capping stay exactly where they are.

  6. 06Markin

    Return exposure and read the holdout

    Currents flows exposure back keyed to the decision ID, so every action is read against the randomised control instead of against last month.

Measurement

How you know whether it worked

Holdout
A global randomised holdout that keeps receiving the pre-existing programme, so the read is arbitration versus business as usual.
Window
Eight to twelve weeks. Shorter reads capture novelty, not lift.
Primary result
Incremental revenue per reachable customer against the holdout.

Guardrails

  • Unsubscribe and complaint rate.
  • Message volume per customer, which should not rise.
  • Cannibalisation of actions that were already working.
  • Share of customers where no action clears the value bar.
Size the holdout for your own base

Illustrative only

A worked example

Illustrative shape of a first deployment, to show what is decided where.

Illustrative worked example
Reachable customers per week600,000
Candidate actions in the set7, plus 'no action'
Decided by MarkinWhich one, for whom, and why
Decided by BrazeWhen it sends, on which channel, under which cap
HoldoutRandomised, receives the existing programme
ReadIncremental revenue per reachable customer over 12 weeks

Nothing about the canvas library is rebuilt. The branch is the only structural change.

Run it on your own numbers

The arithmetic, spelled out

Holdout size is the constraint people get wrong, not the model. For a two-sided test at 95% confidence and 80% power on a revenue-per-customer metric, n per group is approximately 16 x (standard deviation / minimum detectable effect) squared.

Worked arithmetic for this playbook
InputValue
Reachable customers per week600,000
Baseline revenue per reachable customer per 12 weeks$18.00
Standard deviation of that figure$54.00 (three times the mean, typical for skewed revenue)
Minimum detectable effect you care about2% of $18.00 = $0.36
n per group16 x (54 / 0.36)^2 = 16 x 22,500 = 360,000
Implied holdout as a share of the weekly reachable baseFeasible: 360,000 is well inside 600,000 accumulated over a 12 week window
If you only ran 50,000 customers per groupSmallest detectable effect becomes 54 x sqrt(16 / 50,000) = $0.97, or 5.4%

A 2% revenue effect on this base needs roughly 360,000 customers per group over the window. Below about 50,000 per group, anything under a 5% effect is indistinguishable from noise, and the programme will be judged on a number the test could never have measured.

Inputs are illustrative. The point that transfers is the shape: revenue distributions are skewed, so the standard deviation is large and small holdouts cannot see realistic effects.

Timeline

How long it takes to a first measured result

  1. 01Week 1

    Currents and warehouse connection

    Braze Currents lands message and engagement events in the warehouse, and profile and subscription state is mapped. Nothing is written back yet.

  2. 02Week 2

    Action set defined with the lifecycle team

    Every action already running in Braze is listed, plus the ones the business would run given a reason, plus an explicit 'no action'.

  3. 03Weeks 3 to 4

    Value model and arbitration

    Each action is valued per customer on expected incremental margin, and the arbitration rule and its audit trail are agreed.

  4. 04Week 5

    Attribute write-back and one canvas branched

    Decisions land as custom attributes and a single canvas is branched on them. One journey first, not the whole library.

  5. 05Weeks 6 to 7

    Rollout across the canvas library

    Remaining canvases add the branch once the write-back has been observed to be stable.

  6. 06Weeks 13 to 17

    First causal read

    Eight to twelve weeks after the global holdout was fixed. Earlier reads measure novelty.

Technical detail

What is read and written, field by field

Braze

Read

  • User profiles, custom attributes and subscription groups via the /users/export endpoints
  • Currents event streams: message sends, opens, clicks, conversions, unsubscribes
  • Canvas and campaign metadata for the action inventory

Written

  • markin_next_best_action (string): the chosen action key
  • markin_decision_id (string): joins exposure back to the decision
  • markin_decision_reason (string): why this action won, for audit
  • markin_decided_at (time) and markin_holdout (boolean)
  • Written through /users/track, batched

Write hourly to daily for journey branching; for send-time or in-app decisions, a synchronous decision API call at render time instead.

Snowflake or your warehouse

Read

  • Revenue, plan and order history keyed to the Braze external_id
  • Product behaviour events
  • Currents tables for exposure

Written

  • Decision and exposure tables keyed by markin_decision_id

Continuous ingest, daily decision batch.

Segment or your CDP

Read

  • Identity resolution and consent state across channels

Written

  • Nothing. Identity stays where it already lives.

Read only.

Effort

What it asks of your team

People needed on the customer side
WhoHow much of their time
Lifecycle or CRM managerThe main counterpart: around a day a week for the action set, the branch and the review of decisions.
Data engineerAround 3 days in weeks 1 and 2 for Currents and warehouse access.
Marketing operationsHalf a day to add the branch pattern and confirm capping is unaffected.
AnalyticsOne session to agree the primary metric and the holdout size before launch.

What normally goes wrong

Arbitrating by propensity to open

The most clickable message is rarely the most valuable one. Ranking by engagement quietly optimises for cheap actions and flat revenue.

Rebuilding delivery inside the decision layer

Braze already handles capping, quiet hours, localisation and deliverability. Duplicating that creates two sources of truth and a governance argument you will lose.

No 'do nothing' option

Sending the best of a bad set is still a bad send. Silence must be able to win the arbitration.

Losing the decision ID

If exposure cannot be joined back to the decision, the programme produces reporting instead of evidence.

Questions this playbook answers

  • How do I add next best action to Braze?
  • Can Braze decide the best offer per customer?
  • How do I arbitrate between competing campaigns in Braze?
  • What does a decision layer add on top of Braze?
  • How do I run a holdout across all Braze canvases?

Frequently asked

Does Braze already do next best action?
Braze orchestrates journeys extremely well and can personalise content within them. What it does not do is value every competing action per customer on expected margin and arbitrate to one. That decision layer sits above the journey, which is why the two coexist rather than compete.
How fast does the decision reach Braze?
Attribute write-back arrives at your sync interval, which suits daily and weekly journeys. Where a decision has to be made at the moment of the send or the screen, Markin answers a decision API call at render time instead.
Do we have to change our canvases?
You add a branch that reads the decision attribute. Templates, audiences, capping, localisation and send-time logic stay as they are.
What happens if Markin returns no action?
The canvas takes its default path, which is normally to send nothing. Being able to decide against contact is a large part of where the margin comes from.
How do we prove it worked?
A randomised holdout keeps receiving the previous programme for the whole measurement window, and exposure returns to Markin through Currents keyed to the decision ID. The read is a comparison between two concurrent groups, never between two time periods.

Run this decision against your own data.