Skip to main content
Score Streaks are a campaign type that tracks how consistently a customer repeats a specific action over time. Each qualifying event extends the streak and increases the customer’s score. When the score reaches a configured milestone, rewards are automatically granted.

How score streaks work

A score streak campaign tracks three layered ideas: time windows (periods), consecutive activity (streaks), and cumulative score (milestones).

Periods and loss conditions

Every time a customer earns a score point, the campaign opens a period window — a countdown timer during which the customer must send the next qualifying event to keep the streak alive. If the timer runs out before the next event, the cycle is lost: the streak resets to zero and a new cycle begins. The loss window is defined by loss.conditions[0]:
Supported units: MINUTES, HOURS, DAYS, WEEKS, MONTHS.

Cycles

A cycle is one continuous run of activity without a loss. Each loss or reset starts a fresh cycle identified by a new current_cycle_id. This means multiple cycles can exist in a single streak record over its lifetime, and the history events are stamped with the cycle they belong to.

Milestones

Rules in a score streak campaign define score thresholds that trigger rewards. When a customer’s current_score reaches or exceeds a milestone, that milestone’s effects (rewards) are granted once per milestone per cycle.
If the score crosses multiple milestones at once (e.g. from 0 to 5), only the highest applicable milestone fires.

Scheduled resets

Optionally, a campaign can define a reset calendar that forcefully closes the active cycle on a schedule — daily, weekly, or monthly. This is independent of the loss condition: a customer with a perfect streak will still be reset on the configured date.

Score streak lifecycle

History events stored in the events JSON column:

Campaign configuration

Milestone rules

Each rule in a score streak campaign must have a milestone score value. When the customer’s score reaches that value within a cycle, the rule’s effects are applied. Multiple rules can define different reward tiers:
  • Conditions in milestone rules are ignored; only milestone and effects matter.
  • When the score reaches milestone 10, only that rule fires — the lower milestones (1, 5) do not fire again for the same score.
  • If a score crosses a milestone for the first time in a cycle, the reward is granted. If the same milestone is crossed again later in the same cycle (e.g. after a reversal), the reward is granted again.

Event reversal behavior

When a source event is reversed:
  1. All GAIN and MILESTONE history events from that source are marked reversed_at.
  2. An EVENT_REVERSAL history event is appended with the negative score delta.
  3. If the reversed event was in the active cycle, current_score, current_streak, period_score, and period_event_count are decremented.
  4. The highest_milestone_score is recalculated from surviving milestone events.
  5. If the score drops below a previously reached milestone, re-triggering the qualifying event will grant the milestone reward again.
Reversal is idempotent: reversing the same event twice has no additional effect.

Manual admin reset

Support operators can force-reset a customer’s active streak cycle without waiting for the loss cron or a scheduled reset. This appends a MANUAL_RESET history event, starts a new current_cycle_id, and zeros score counters for the active cycle. Endpoint (internal): POST /api/admin/score-streaks/reset Requires the checksum header with the CRON_AUTH_SECRET value. This endpoint is not part of the public Storefront API.

Comparison with punch cards