"loyalty", "status") is an independent track with ordered levels. You might define a loyalty track with Silver, Gold, and Platinum levels, or a status track for new, active, and churned members.
Tiers can advance automatically based on counter thresholds, or be set directly by rules. Retention modes control how long a tier lasts, and downgrade policies determine what happens when qualification lapses.
Tier Types and Levels
A tier type defines a progression track. Each type contains ordered levels, whererank determines the hierarchy. Higher rank means a higher tier.
Tier Type Fields
| Field | Required | Description |
|---|---|---|
key | Yes | Unique identifier (lowercase alphanumeric and underscores, starts with a letter) |
display_name | No | Human-readable name |
levels | Yes | Ordered list of tier levels |
lifecycle | No | Retention, qualification, and downgrade configuration. Omit for rules-only tiers. |
Level Fields
| Field | Required | Description |
|---|---|---|
key | Yes | Unique within the tier type |
rank | Yes | Integer determining hierarchy. Higher rank = higher tier. Must be unique within the type. |
display_name | No | Human-readable name |
qualification | No | Counter-based criteria for automatic advancement |
benefits | No | Arbitrary JSON returned with tier state |
color | No | Hex color code for UI rendering |
icon_url | No | Icon URL for UI rendering |
Qualification
Qualification criteria determine when a participant automatically advances to a tier level. Each criterion checks a participant counter against a threshold.| Field | Description |
|---|---|
mode | ALL (every criterion must be met) or ANY (at least one) |
counter | Counter key to evaluate on the participant |
operator | >=, >, ==, <=, < |
threshold | Numeric value to compare against |
SET_TIER rule action fires for the same tier type during the same event, auto-evaluation is skipped for that type. This lets rules take explicit control when needed.
Benefits
Each level can carry abenefits object, a freeform JSON payload that Scrip stores and returns whenever you query a participant’s tier state. Use benefits to attach level-specific data that your application acts on: multipliers, feature flags, discount rates, access grants, or anything else tied to the level.
"benefits": {"points_multiplier": 2.0, "lounge_access": true, "support_priority": "high"}. Your application reads these values and applies the corresponding behavior.
Benefits are also accessible in rule conditions via participant.tiers.<key>.benefits, so you can write rules that check a participant’s current benefits before taking action:
Retention Modes
Theretention config in lifecycle controls how long a tier lasts once achieved.
| Mode | Behavior |
|---|---|
PERIOD_BASED | Tier is re-evaluated at the end of each qualification period. The participant keeps their tier until the next period boundary. |
ACTIVITY_REFRESH | Tier expires after the specified duration of inactivity. Each event processed for the participant resets the timer. |
Qualification Periods
ForPERIOD_BASED retention, the qualification period defines the evaluation cycle:
| Type | Behavior |
|---|---|
CALENDAR_YEAR | January 1 to December 31 |
FIXED_YEAR | Custom start date via start_month and start_day |
NONE | No periodic re-evaluation |
tier_evaluation system event via an internal automation that re-evaluates all tiers and applies the downgrade policy.
Activity Refresh
ForACTIVITY_REFRESH, the duration is specified in hours (e.g., "8760h" for one year). The timer restarts on every external event processed for the participant. When the timer expires without new activity, Scrip fires a tier_expiration system event via an internal automation and applies the downgrade policy.
Downgrade Policies
When a tier expires or the qualification period ends, the downgrade policy determines the participant’s new level.| Mode | Behavior |
|---|---|
DROP_TO_QUALIFYING | Find the highest level where qualification criteria are currently met. If none qualify, the tier is removed entirely. |
DROP_ONE | Drop exactly one rank below the current level. |
HOLD | Keep the current tier indefinitely, regardless of qualification. |
DROP_TO_QUALIFYING. It re-evaluates the participant’s counters at downgrade time and places them at the level they actually qualify for.
Set min_level to establish a floor that the participant can never drop below, regardless of qualification.
Grace Periods
Setgrace_days on the downgrade policy to defer downgrades. When a downgrade would normally occur, the tier is extended by the grace period instead. If the participant re-qualifies during the grace window, the downgrade is cancelled. If the grace period expires without re-qualification, the downgrade proceeds.
Counter Rollover
Thecounters config controls what happens to qualifying counters at the end of a qualification period.
| Rollover | Behavior |
|---|---|
NONE | Qualifying counters reset to 0 at period end |
EXCESS | Qualifying counters carry over the amount above the current tier’s threshold |
EXCESS rollover sets the counter to 500 for the new period.
The qualifying array lists which counter keys are affected by rollover. Counters not in this list are left unchanged.
SET_TIER Rule Action
Rules can assign a tier directly using theSET_TIER action. This is useful for promotions, overrides, or tier logic that goes beyond counter thresholds.
| Field | Required | Description |
|---|---|---|
tier | Yes | Tier type key (e.g., "loyalty") |
level | Yes | Level key to assign (e.g., "platinum") |
expiry | No | Duration (e.g., "8760h") or RFC 3339 timestamp. Schedules automatic expiration. |
target | No | Defaults to the event’s participant. Use {"type": "GROUP", "group_id": "..."} for group tiers. |
expiry is set, Scrip schedules a tier_expiration system event at that time. If the participant qualifies at expiration, they keep the tier. Otherwise, the downgrade policy applies.
Tier State in CEL
Tier state is available in rule conditions viaparticipant.tiers:
| Field | Type | Description |
|---|---|---|
level | string | Current level key |
rank | int | Current level rank |
benefits | map | Benefits JSON from the level definition |
acquired | string | RFC 3339 timestamp of when the tier was achieved |
expires | string | RFC 3339 timestamp of when the tier expires (null if no expiry) |
groups[0].tiers.