Rule Action Reference¶
The Rule Action Reference explains the types of Engine Actions available for use within RCX Rules.
Member Management¶
Lookup Member
Lookup Member¶
Description
The action resolves the member for the current activity and populates the execution context with member details. Since it is typically the first action in a flow, it also performs duplicate-activity detection on activity.externalTxnId.
Parameters
None. Uses the current activity context.
JavaScript API
Outputs
Populates the Context with:
member— the resolved member object.loyaltyIds— array of loyalty IDs associated with the member.activity.memberID— set if the member was resolved by loyalty ID.activity.originalMemberID— original member ID (pre-merge if?resolveMerge=true).activity.loyaltyID— defaulted to the primary or default-card-type loyalty ID when the activity didn't supply one.duplicateAct— set on the context when a priorProcessedactivity with the sameexternalTxnIdis found on the same member (used downstream).
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | Could not find member with member id %s | The provided memberID doesn't resolve to a member. |
| 4002 | Could not find member with loyalty id %s | The provided loyaltyID doesn't resolve to a member and auto-enroll didn't apply. |
| 4002 | Could not find member defined in 'Accrue To' for loyaltyID %s | The loyalty code has an accrueTo pointer that doesn't resolve to a member. |
| 2063 | Duplicate activity with external transaction id %s | A Processed activity with the same externalTxnId exists for the member (and isn't cancelled). |
| 2079 | The loyalty id %s passed as part of activity is not valid. | Card validation is enabled on the program and no matching LoyaltyCard was found in New status (unless the ignoreDupLID special flag is set). |
Additional Considerations
- Lookup sequence:
- If
activity.memberIDis set, the member is fetched by_id. - Otherwise, the loyalty ID is looked up via the
LoyaltyIDmodel and the resultingmemberIdis used. - If still not resolved and the activity has a loyalty ID, an anonymous member is created and auto-enrolled into the program (subject to program settings and optional loyalty-card validation).
- If
- When a loyalty code has
accrueToset and the activity is anAccrual, the resolved member is replaced by theaccrueTotarget. - If the resolved member is missing purses defined by the program, they are added before the member is returned.
- When the activity URL includes
?resolveMerge=true, merged-away members are resolved to their survivor. - Duplicate-activity detection checks both the member's current activities and
ActivityHistory; for matches without an embeddedresult.log, it pulls the log from Elasticsearch (unlessprogram.enrollSettings.disableEsLogsLookUpis set).
Lookup Peer Member
Lookup Peer Member¶
Description
Loads a peer member into the engine execution context using LoyaltyID or MemberID. Sets Context.peer for use by subsequent actions.
What is a Peer Member?
A peer member is another member within the same loyalty program who can be identified and loaded during an activity transaction to perform point operations on their account.
When processing an activity for one member, you can look up a peer member using their Loyalty ID or Member ID, and then add or redeem points on the peer member's account.
Parameters
| Parameter | Type | Description |
|---|---|---|
| Value | String | Member ID or Loyalty ID of the peer to look up |
JavaScript API
Outputs
The action populates Context.peer with the peer member object returned from the member lookup service.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | No member found with memberId "%s" in program "%s" | The provided ObjectId doesn't resolve to a member in the current program. |
| 4002 | No member found with loyaltyID "%s" in program "%s" | The provided loyalty ID doesn't resolve to a member in the current program. |
| 2145 | The target member must not be same as the source member | The provided value resolves to the context member. |
Additional Considerations
- The peer is only stored on
Context.peer; it doesn't affect the primary activity or member objects. - Loading the peer alone does not persist any changes to it. A subsequent peer action (such as Add Points To Peer or Redeem Points From Peer) is required to write changes back.
- This action is typically followed by Add Points To Peer or Redeem Points From Peer.
Lookup Account Members
Lookup Account Members¶
Description
The action looks up the Account that contains the context member and populates all of its other members (linked members) into the execution context. Only members in the same program are included.
Parameters
None. Uses the current member context.
JavaScript API
Outputs
Populates Context.linkedAccount with the matched account plus:
members— array of linked member objects from the same program (excluding the context member). If the member belongs to no account, this is an empty array.
Linked members are made available for reuse by later actions in the same flow.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | Member not found | Reported if there is no context member set (Lookup Member must run first). |
Other errors are propagated from the underlying storage layer.
Additional Considerations
- The action is a no-op if
Context.linkedAccountis already populated. - If any linked member is missing purses defined by the program, they are added before the member is returned.
- Tier display names are translated on linked members when the program's tier-name translation setting is enabled.
Lookup Member Aggregates
Lookup Member Aggregates¶
Description
The action is used to lookup and populate aggregate metrics for the member across different time periods.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Aggregates | String/Array | Text | Names of aggregates to lookup; can be a regex pattern such as "/^Total Spend$/i" |
| Aggregate Types | String/Array | Text | Optional. Types of aggregates (daily, weekly, monthly, and so on.) |
| From Date | Date | Text | Optional. Start date for aggregate lookup |
| To Date | Date | Text | Optional. End date for aggregate lookup |
JavaScript API
Outputs
Populates the Context with one collection per requested aggregate type:
Context.dailyAggs,Context.weeklyAggs,Context.monthlyAggs,Context.quarterlyAggs,Context.halfYearlyAggs,Context.yearlyAggs,Context.lifetimeAggs.
Each entry includes metricName, metricAggValue, memberId, lastAggDate, the period field(s) for that bucket, and a resolved policyId (from a matching AggregatePolicy or PursePolicy in the same program when one exists). Transient member aggregates are merged on top of database results.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | From Date should be less than or equal to current date in Lookup Member Aggregates action | fromDate is later than toDate (when both supplied) or later than the activity date (when only fromDate is supplied). |
| 4011 | To Date should be greater than or equal to current date in Lookup Member Aggregates action | Only toDate is supplied and it is earlier than the activity date. |
| 4011 | (date validation error) | fromDate or toDate fails generic date validation (invalid format, out of allowed year range). |
| 4033 | Aggregates should be a string or array in Lookup Member Aggregates action | The aggregates parameter is missing, empty, or not a string/array. |
| 4033 | Multiple regex patterns are not allowed in Lookup Member Aggregates action | More than one entry in the aggregates list is a regex pattern. |
| 4033 | Cannot mix regex patterns with string(s) in Lookup Member Aggregates action | The aggregates list contains both a regex pattern and a plain string. |
| 4033 | Aggregate Types should be a string or array in Lookup Member Aggregates action | The types parameter is provided but isn't a string or array. |
| 4042 | Invalid regex pattern in Lookup Member Aggregates action | Malformed or invalid regex pattern. |
| 4043 | Regex pattern too long in Lookup Member Aggregates action | Regex pattern exceeds the 100-character limit. |
| 4044 | Invalid regex flag in Lookup Member Aggregates action | Unsupported regex flag used. |
| 4045 | Duplicate regex flags in Lookup Member Aggregates action | Same flag repeated in regex pattern. |
| 4046 | Regex pattern contains potentially dangerous constructs that could cause ReDoS attacks in Lookup Member Aggregates action | Dangerous regex pattern detected. |
| 4047 | Regex pattern cannot be empty in Lookup Member Aggregates action | Empty regex pattern provided. |
| 4048 | Invalid regex format in Lookup Member Aggregates action | Regex format is incorrect. |
Additional Considerations
- Supports multiple aggregate types: daily, weekly, monthly, quarterly, half-yearly, yearly, lifetime
- Supports regex patterns for aggregate names.
- Regex has a limit of 100 characters.
- Validates date ranges against current activity date
- Returns empty results if no aggregates found
- All dates are adjusted for timezone offset from program settings (default time zone)
Populate Aggregates
Populate Aggregates¶
Description
Loads the value of a single metric across one or more aggregate period types and writes them onto the context, keyed by metric name. This differs from Lookup Member Aggregates, which queries multiple metrics across a date range and returns arrays of aggregate documents.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Metric Name | String | Text | The metric (aggregate or purse policy name) to load. Required. |
| Types | String | Text | Optional. Comma-separated list of period types — any of daily, weekly, monthly, quarterly, halfyearly, yearly, lifetime. Defaults to all seven. |
JavaScript API
Outputs
Populates two objects on the context, keyed first by metricName, then by period type:
Context.populatedMemAggs[metricName][<type>]— the member-scoped aggregate value for each requested type.Context.populatedAggs[metricName][<type>]— the global aggregate value for each requested type (when one exists).
If the member has a transient (in-memory) aggregate value for a type, that value is used in preference to the stored one.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| (plain Error) | Metric Name is Empty | metricName is missing or empty. Raised as a generic Error (not an RLE-coded error). |
| (plain Error) | Invalid Aggregate type/types | One or more entries in types isn't a recognized period type. |
Additional Considerations
- The activity date is shifted by the program's
enrollSettings.aggregateOffsetTZbefore computing the period buckets (day/week/month/quarter/half-year/year), so values align with the program's reporting timezone. - Use this action when a rule needs to check a single metric's value at multiple roll-ups (for example, comparing daily spend vs. lifetime spend in one condition). Use Lookup Member Aggregates when you need to scan many metrics or filter by a date range.
Update Member Aggregate
Update Member Aggregate¶
Description
The action is used to update a member's aggregate value for a given policy.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Policy ID | String | Text | The ID of the aggregate policy to update or 'Variable' for custom aggregates |
| Aggregate Name | String | Text | The name of the aggregate (required if policyId is 'Variable') |
| Value | Number | Text | The value to add to the aggregate |
| Aggregate Date | Date | Text | The date to associate with the aggregate update |
| Expiration Date | Date | Text | The expiration date for the aggregate |
JavaScript API
Outputs
Updates member's aggregate values in Context.aggregates.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4033 | aggregate name is invalid in Update Member Aggregate action | Reported when policyId is Variable and aggregateName isn't a non-empty string. |
| 4033 | value is invalid in Update Member Aggregate action | Reported when value isn't a number. |
| 4011 | (date validation error) | Reported when aggregateDate or expirationDate is invalid. |
| 1805 | Aggregate policy with id %s not found / Aggregate policy with name %s not found | The specified policy can't be resolved (looked up by _id, or by name + program when Variable). |
| 2106 | Aggregate cannot be updated as policy %s is not effective | The activity date is before the policy's effectiveDate. |
| 2107 | Aggregate Policy %s has already expired on %s. | The activity date is after the policy's expirationDate. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the aggregate policy. |
Additional Considerations
- If
valueis 0 the action is a no-op (returns an empty array). - When
policyIdisVariable, bothaggregateNameandvalueare validated; otherwise onlyvalueis validated. - The
aggregateDatedefaults to the activity's UTC date when omitted. - The action appends to (or updates an existing entry in)
Context.aggregates. When the aggregate types includelifetime, the policy'sexpirationDateis used as the default expiration unless overridden. - If
program.enrollSettings.raiseMetricEventPerInstanceis true, every call produces a new aggregate entry; otherwise repeat calls for the same policy on the same member sum into the existing entry. - Divisions on the new aggregate record default to the policy's divisions (unless the
Aggregatedivision-update skip flag is set).
Lookup Member Loyalty IDs
Lookup Member Loyalty IDs¶
Description
The action is used to lookup and populate loyalty IDs associated with the current member.
Parameters
None. Uses the current member context.
JavaScript API
Outputs
Populates Context.member.loyaltyIds with an array of loyalty ID objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns early (no-op) if no member is found in context.
- Returns an empty array if the member has no loyalty IDs.
- If
Context.member.loyaltyIdsis already populated (for example, by Lookup Member), the database results are concatenated onto the existing array — duplicates are not deduplicated by this action.
Lookup Merge Victims
Lookup Merge Victims¶
Description
The action is used to find all members that were merged into the current member (victims of merge operations).
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Member IDs | String/Array | Text | Optional. Specific member IDs to lookup. If not provided, returns all merge victims |
JavaScript API
Outputs
Populates Context.mergeVictim.members with an array of victim member objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- The action is a no-op (logs a warning and returns) if no context member is set.
- If
memberIdsis supplied (string or array) and any entry isn't a valid ObjectId, the action logs a warning and skips — it does not throw. - Only the merge-victim members associated with the current context member are returned.
Context.mergeVictimis only set when at least one victim is found; otherwise it remains unset.
Add Division
Add Division¶
Description
Adds a division to a member's profile. This action enables you to associate a member with a specific division within the program.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Division | String | Dropdown | The ID of the division to add. Choose Variable to supply the name at run-time via the Division Name parameter. |
| Division Name | String | Text | Required when Division is Variable. The name of the division to add. |
JavaScript API
Outputs
Adds the division to the member. The member and activity are updated when the rule flow completes.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1713 | Please provide valid division | divisionId is missing. |
| 2151 | Invalid divisionId "%s" passed | divisionId isn't Variable and isn't a valid ObjectId. |
| 2158 | Division "%s" not found | The division can't be resolved from _id (or name when Variable). |
| 2159 | Expected single division value but received array of values "%s" | Either divisionId or divisionName was provided as an array. |
| 2159 | Division name is required when a variable is used for the divisionId | divisionId is Variable but divisionName is missing. |
| 4025 | Member cannot be created/edited as the program does not belong to "%s" division | The resolved division isn't in the program's divisions list. |
Additional Considerations
- The division must exist in the
Divisioncollection. - The division must be one of the program's configured divisions.
- If the member already belongs to the division, the action is a no-op (no save).
- The action does not check a permission for adding divisions (only removal goes through the
Member.Divisions.RemoveACL check).
Remove Division
Remove Division¶
Description
Removes a division from a member's profile. This action disassociates a member from a specific division within the program.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Division | String | Dropdown | The ID of the division to remove. Choose Variable to supply the name at run-time via the Division Name parameter. |
| Division Name | String | Text | Required when Division is Variable. The name of the division to remove. |
JavaScript API
Outputs
Removes the division from the member. The member and activity are updated when the rule flow completes, even if the member did not have the division (the action still marks both as dirty).
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1713 | Please provide valid division | divisionId is missing. |
| 2151 | Invalid divisionId "%s" passed | divisionId isn't Variable and isn't a valid ObjectId. |
| 2155 | No permission to remove division on member | The current user lacks delete permission on Member.Divisions.Remove. |
| 2158 | Division "%s" not found | The division can't be resolved from _id (or name when Variable). |
| 2159 | Expected single division value but received array of values "%s" | Either divisionId or divisionName was provided as an array. |
| 2159 | Division name is required when a variable is used for the divisionId | divisionId is Variable but divisionName is missing. |
Additional Considerations
- The division must exist in the
Divisioncollection. - The user must have
deletepermission onMember.Divisions.Remove(ACL-enforced). - Unlike Add Division, this action does not require the division to be in the program's
divisionslist. - If the member doesn't currently have the division, the action still resolves the division and writes a (functionally unchanged) divisions array; no error is raised.
Points & Purses¶
Add Points
Add Points¶
Description
The action is used to accrue points to a purse, to reward some activity posted for the member. The action allows setting the purse, points expiration date, escrow date and specifying the accounting type of the points.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to add. Must be positive, whole number. |
| Accounting Type | String | Normal/Non-Revenue |
Categorizes the earn - typically non-revenue earn is given for non-purchase activities. |
| Expiration Date | Date/Time | JS Date | Expiration date for points. Defaults to Purse Policy setting. |
| Escrow Date | Date/Time | JS Date | Escrow date for points. Defaults to Purse Policy setting. |
Outputs
None
JavaScript API
Events Triggered
Generates the L2 AddPointsEvent when points are added.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2040 | Can not find purse in member with _id %s | Reported if the purse name is invalid |
| 2052 | The points to be added to purse %s are invalid | Reported if points value is invalid |
| 2084 | Accrual escrow failed | When escrow operation fails |
| 2070 | Accrual expiry failed | When expiry operation fails |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- In the Rule Builder the Purse Name is a drop-down, showing all the Purse Policies. You can select
Variableif you would like to compute thePurse Nameparameter at run-time. - If points is 0, operation is skipped
- Points can't be negative
- If rule has countLimit or budget > 0, rule context is updated
- To model floating point values (for example, USD), use the lowest granularity (for example cents)
Redeem Points
Redeem Points¶
Description
The action is used to redeem points from a member's purse. The action validates available balance before redemption and handles locked points appropriately.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to redeem. Must be positive, whole number. |
JavaScript API
Events Triggered
Generates the L2 RedeemPointsEvent when points are redeemed.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2040 | Can not find purse in member with _id %s | Reported if the purse name is invalid |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | When there are insufficient points |
| 2053 | The points to be redeemed from purse %s are invalid | When points value is invalid |
| 1762 | Transaction cannot update members | When transaction fails to update members |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- In the Rule Builder the Purse Name is a drop-down, showing all the Purse Policies. You can select
Variableif you would like to compute thePurse Nameparameter at run-time. - If points is 0, operation is skipped.
- Points can't be negative.
- Checks for available balance before redeeming.
- Considers locked points when calculating available balance.
- To model floating point values (for example, USD), use the lowest granularity (for example, cents).
Redeem Points with Accounting Type
Redeem Points with Accounting Type¶
Description
The action is used to redeem points from a member's purse with the ability to specify an accounting type for the redemption. The action validates available balance before redemption and handles locked points appropriately.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to redeem. Must be positive, whole number. |
| Accounting Type | String | Normal/Non-Revenue |
Categorizes the redemption. Normal points represent revenue-generating transactions where the company recognizes the monetary value of redeemed points as a cost against earned revenue. Non-Revenue points are issued for promotional, goodwill, or bonus purposes and don't impact the company's revenue accounting since no corresponding revenue was originally recorded. |
JavaScript API
Events Triggered
Generates the L2 RedeemPointsEvent when points are redeemed.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2040 | Can't find purse in member with _id %s | Reported if the purse name is invalid |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | When there are insufficient points |
| 2053 | The points to be redeemed from purse %s are invalid | When points value is invalid |
| 1762 | Transaction can't update members | When transaction fails to update members |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- In the Rule Builder the Purse Name is a drop-down, showing all the Purse Policies. You can select
Variableif you would like to compute thePurse Nameparameter at run-time. - If points is 0, operation is skipped
- Points can't be negative
- Checks for available balance before redeeming
- Considers locked points when calculating available balance
- To model floating point values (for example USD), use the lowest granularity (for example cents)
- The Accounting Type parameter allows categorization of redemptions for reporting and analytics purposes
- Non-Revenue accounting type is typically used for redemptions that don't involve revenue transactions
Linked Add Points
Linked Add Points¶
Description
The action is used to add points to multiple linked members' purses in a single operation. Points can be added with different amounts for each member, with optional accounting type, expiration date, and escrow date.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Array/Number | Array of Objects or Integer | Either a single points value for context member, or array of objects mapping member IDs to points and activities. |
| Accounting Type | String | Normal/Non-Revenue |
Categorizes the earn - typically non-revenue earn is given for non-purchase activities. |
| Expiration Date | Date/Time | JS Date | Expiration date for points. Defaults to Purse Policy setting. |
| Escrow Date | Date/Time | JS Date | Escrow date for points. Defaults to Purse Policy setting. |
Outputs
Returns array of updated purses.
JavaScript API
Events Triggered
Generates the L2 AddPointsEvent for each member involved.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2040 | Can not find purse in member with _id %s | Reported if the purse name is invalid |
| 2052 | The points to be added to purse %s are invalid | Reported if points value is invalid |
| 2084 | Accrual escrow failed | When escrow operation fails |
| 2070 | Accrual expiry failed | When expiry operation fails |
| 2091 | Linked member with id %s not found to add points | When specified linked member isn't found |
| 2000 | Please provide activity in options of LinkedAddPoints action | When activity is missing for linked member |
| 4002 | A linked action linkedAddPoints was used with only one member, who is not the context member | Reported when array form is used with one entry that isn't the context member |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- In the Rule Builder the Purse Name is a drop-down, showing all the Purse Policies. You can select
Variableif you would like to compute thePurse Nameparameter at run-time. - If points is 0, operation is skipped.
- Points can't be negative.
- If rule has countLimit or budget > 0, rule context is updated.
- When using array format, each object must have:
- memberId as key.
- amount: points to add.
- activity: activity object for the linked member.
- For single member operations, points can be a simple number.
- To model floating point values (for example, USD), use the lowest granularity (for example, cents).
- Activities are automatically created and added to linked members.
Linked Redeem Points
Linked Redeem Points¶
Description
The action is used to redeem points from multiple linked members' purses in a single operation. Points can be redeemed in different amounts from each member; an activity is generated for each linked (non-context) member to record the redemption.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Array/Number | Array of Objects or Integer | Either a single points value (redeems from the context member), or an array of single-key objects mapping memberId to { amount, activity }. |
Outputs
Returns the array of updated purses for the context member. For linked members, the redeemed purse is added to the linked member's activity result log instead of the return value.
JavaScript API
Events Triggered
Generates the L2 RedeemPointsEvent for each member affected.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | A linked action linkedRedeemPoints was used with only one member, who is not the context member | Reported when array form is used with one entry that isn't the context member |
| 2133 | Linked member with id %s not found to redeem points | Member specified in the points array isn't found in the linked account |
| 2000 | Please provide activity in options of LinkedRedeemPoints action | Activity object missing for a linked (non-context) member |
| 2040 | Can not find purse in member with _id %s | Reported if the purse name is invalid for the member |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | Insufficient points and the purse policy's overdraft limit cannot cover the request |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- In the Rule Builder the Purse Name is a drop-down, showing all the Purse Policies. You can select
Variableif you would like to compute thePurse Nameparameter at run-time. - If points is 0, operation is skipped.
- When
pointsis a plain number, the action redeems from the context member only. - When
pointsis an array, each entry is a single-key object: the key is the member ID and the value is{ amount: <number>, activity: <activity object> }. Theactivityis required for any member other than the context member — it becomes a linked activity, validated and added to that member. - Available balance is computed as
purse.availBalance - lockedPointsevaluated at the activity date plus UTC offset; only locked points whoselockedTillDateis still after the activity date are subtracted. - If the request exceeds the available balance, the purse policy's
overdraftLimitis consulted; redemption proceeds only if the policy allows enough overdraft to cover the request. - Linked redemptions accumulate into
Context.result.data.linkDraw(set on the context member's activity). - To model floating point values (for example, USD), use the lowest granularity (for example, cents).
Targeted Redeem Points
Targeted Redeem Points¶
Description
The action is used to redeem points from a specific activity's accruals.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Policy ID | String | Text | ID of the purse policy |
| Purse Name | String | Text | Optional. Name of purse if Policy ID is 'Variable' |
| Points | Number | Integer | Number of points to redeem |
| Target Activity | String | Text | ID of activity whose accruals to redeem from |
JavaScript API
Events Triggered
Generates L2 RedeemPointsEvent when points are redeemed.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1720 | Invalid target activity | The provided target activity ID is missing or not a valid ObjectId |
| 2040 | Can not find purse in member with _id %s | The specified purse wasn't found for the member |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | Insufficient points available in the purse (also covers insufficient points in target activity's accruals) |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- Validates target activity ID is valid ObjectId.
- Validates purse exists and belongs to member.
- Checks available points in target activity's accruals.
- Can't redeem more points than available in target activity.
- Points can't be redeemed after the purse period close date.
- Generates events before database updates.
- Updates both purse balance and accrual records.
Add Points To Peer
Add Points To Peer¶
Description
Adds points to the peer member’s purse. The action expects a peer to already be populated in the execution context via Lookup Peer Member. It creates a linked activity for the peer (type: “Peer Add Points”) and updates the peer’s purse balance.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this dropdown and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to add. |
| Activity Payload | Object | JSON | Object to override fields on the generated peer activity (default: type: "Peer Add Points"). Refer to the Using Context Member Instead of Peer section below. |
| Accounting Type | String | Normal/Non-Revenue | Categorizes the earning transaction. Typically, non-revenue earnings are given for non-purchase activities. |
| Expiration Date | Date/Time | JS Date | Expiration date for the points (optional). |
| Escrow Date | Date/Time | JS Date | Escrow date for the points (optional). |
Using Context Member Instead of Peer
By default, this action operates on the peer member loaded via Lookup Peer Member. To operate on the context member instead, wrap the activity in a payload that sets useContextMemberAsPeer: true and places the activity override under an activity key:
When this flag is set to true, the points operation runs on the context member and the override at activity is merged into the generated linked activity. (When the flag is absent or false, the entire payload object is treated as the activity override and applied to the peer member's linked activity.)
JavaScript API
UDF.addPointsToPeer(policyId, purseName, points, activityPayload,
accountingType, expiration, escrowDate, callback)
Peer Member Activity
The peer member must already be populated in the context via the Lookup Peer Member action. A new activity is created for the peer member with the following payload:
{
"type": "Peer Add Points",
"date": context.activity.utcDate || new Date(),
"currencyCode": context.activity.currencyCode,
"memberID": peerMember._id,
"originalMemberID": peerMember._id,
"srcChannelID": context.activity.srcChannelID,
"srcChannelType": context.activity.srcChannelType,
"value": context.activity.value,
"status": "Processed"
}
Outputs
- The purse balance is increased by the specified points on:
- Peer member (default behavior)
- Context member (when
useContextMemberAsPeer: trueis set in Activity Payload)
- A linked peer activity of type “Peer Add Points” is created and attached to the primary activity via
activity.data.peerActivityId. - The callback receives either an error or the result object from the points addition.
Events Triggered
Generates the L2 AddPointsEvent when points are added.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2040 | Cannot find purse in peer/context member with _id %s. | The specified purse (by policy ID or name) doesn't exist on the target member. |
| 2052 | The points to be added to purse %s are invalid. | Reported if the points value is invalid. |
| 4002 | Peer member not found. Please use populatePeer action first. | Lookup Peer Member (populatePeer) must be called before addPointsToPeer (unless useContextMemberAsPeer is set). |
| 4002 | Context member not found. | Reported only when useContextMemberAsPeer is set and the context member is unavailable. |
| 4041 | Division Access Denied for user. | If the user lacks division access for the purse policy. |
Related Actions
Additional Considerations
- If the points value is 0, the action returns an empty array.
- The linked peer activity inherits metadata (date, currency, channel, location, and so on.) from the primary activity unless overridden by the
activityPayloadparameter. - Errors are logged via the internal logger and passed to the callback.
Redeem Points From Peer
Redeem Points From Peer¶
Description
Redeems points from the peer member's purse. The action expects a peer to already be populated in the execution context via Lookup Peer Member. It creates a linked activity for the peer (type: "Peer Redeem Points"), updates the peer member's purse balance, and allows the activity payload to be overridden. The peer's changes are saved when the rule flow completes.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose the Variable in this dropdown and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to redeem. |
| Activity Payload | Object | JSON | Object to override fields on the generated peer activity (default: type: "Peer Redeem Points"). Refer to the Using Context Member Instead of Peer section below. |
Using Context Member Instead of Peer
By default, this action operates on the peer member loaded via Lookup Peer Member. To operate on the context member instead, wrap the activity in a payload that sets useContextMemberAsPeer: true and places the activity override under an activity key:
When this flag is set to true, the redemption runs on the context member and the override at activity is merged into the generated linked activity. (When the flag is absent or false, the entire payload object is treated as the activity override and applied to the peer member's linked activity.)
JavaScript API
Peer Member Activity
The peer member must already be populated in the context via the Lookup Peer Member action. A new activity is created for the peer member with the following payload:
{
"type": "Peer Redeem Points",
"date": context.activity.utcDate || new Date(),
"currencyCode": context.activity.currencyCode,
"memberID": peerMember._id,
"originalMemberID": peerMember._id,
"srcChannelID": context.activity.srcChannelID,
"srcChannelType": context.activity.srcChannelType,
"value": context.activity.value,
"status": "Processed"
}
Outputs
- The purse balance is reduced by the specified points on:
- Peer member (default behavior)
- Context member (when
useContextMemberAsPeer: trueis set in Activity Payload)
- A linked peer activity of type “Peer Redeem Points” is created and attached to the primary activity via
activity.data.peerActivityId. - The callback receives either an error or the result object from the redemption.
Events Triggered
Generates the L2 RedeemPointsEvent when points are redeemed.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | Insufficient points in the target purse |
| 2040 | Cannot find purse in peer/context member with _id %s. | The specified purse (by policy ID or name) doesn't exist on the target member. |
| 4002 | Peer member not found. Please use populatePeer action first. | Lookup Peer Member (populatePeer) must be called before redeemPointsFromPeer (unless useContextMemberAsPeer is set). |
| 4002 | Context member not found. | Reported only when useContextMemberAsPeer is set and the context member is unavailable. |
| 4041 | Division Access Denied for user. | If the user lacks division access for the purse policy. |
Related Actions
Additional Considerations
- If the points value is 0, the action returns an empty array and makes no changes.
- The linked peer activity inherits metadata (date, currency, channel, location, and so on.) from the primary activity unless overridden by the
activityPayloadparameter. - Errors are logged via the internal logger and passed to the callback.
Lock Points
Lock Points¶
Description
The action is used to lock points in a purse until a specified date.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Points | Number | Integer | Number of points to lock |
| Locked Till | Date/Time | JS Date | Date until which the points are locked |
| Tag | String | Text | Optional. Tag to identify the locked points |
JavaScript API
Events Triggered
- Generates L2 LockPointsEvent when points are locked
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | Please provide a valid locked till date | The lockedTill date parameter is invalid or earlier than the activity date |
| 2018 | Can not find purse in member with _id %s | Reported if provided purse is invalid |
| 2080 | The points to be locked from purse %s are invalid | Reported if points value is invalid |
| 2019 | Failed to lock %d points from purse %s because it has only %d points available. | Insufficient point balance for lock operation |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- Validates purse exists and belongs to member.
- Points must be a positive number.
- Locked till date must be on or after the activity date.
- Points can't be locked after the purse period close date.
- Total locked points can't exceed purse balance.
Unlock Points
Unlock Points¶
Description
The action is used to unlock previously locked points in a purse.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse you want to use. If you want the purse name to be variable based on a calculated field, choose Variable in this drop down and fill in the Purse Name field that appears next to the dropdown. |
| Lookup Field | String | Text | Field on the locked-points record to filter by (for example tag). |
| Lookup Value | String | Text | Value to match in the lookup field. |
JavaScript API
Events Triggered
- Generates L2 UnlockPointsEvent when points unlocked
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2081 | Please provide required parameters in UnlockPoints action | Required lookup parameters are missing |
| 2018 | Can not find purse in member with _id %s | The specified purse wasn't found |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy |
Additional Considerations
- Validates lookup field and value are provided.
- Validates purse exists and belongs to member.
- After the purse policy's period close date, the operation is a no-op (the action logs an info message and returns an empty result) instead of an error.
- Updates the locked-points array in the purse.
- Returns the unlocked-points records that were applied to the activity.
- Supports multiple lock records matching lookup criteria.
Expire Balance
Expire Balance¶
Description
The action is used to expire the balance in a purse.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse | String | Dropdown | Select the purse policy to expire balance from |
| Purse Name | String | Text | Optional. Name of the purse when using Variable purse policy |
JavaScript API
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2000 | Please provide required parameters in ExpireBalance action | Purse policy isn't provided, or Variable is selected without a purse name. |
| 2018 | Purse not found | The purse for the given policy ID (or name when Variable) doesn't exist on the member. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Additional Considerations
- Validates purse exists before expiring the balance.
- The
Purse Nameparameter is only used when the policy is set toVariable. - The action zeroes the purse's balance and available balance, adds the previous balance to expired points, and marks the purse as having an in-progress expiration referencing the current activity.
- After the purse policy's period close date, the operation is a no-op (returns the purse unchanged) and only logs an info message.
Expire Accruals
Expire Accruals¶
Description
This action is used to expire the balance associated with accruals that have reached their expiration date within a purse.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse | String | Dropdown | Select the purse policy to expire balance from |
| Purse Name | String | Text | Optional. Name of the purse when using Variable purse policy |
| MemberAvailable balance | Number | Integer | Optional when Evaluate Expired Points is true. Snap of Member available balance to compare with current member state |
| Member lastActivityDate | Date | JS Date | Optional when Evaluate Expired Points is true. Snap of Member lastActivityDate to compare with current member state |
| Points to Expire | Number | Integer | Optional when Evaluate Expired Points is true. Expires the mentioned points if the provided the lastActivityDate and available matches with current member state |
| Evaluate Expired Points | Boolean | true/false | If enabled, points are recalculated and expired at activity execution; otherwise, the provided available balance and last activity date are used to expire the specified points. |
JavaScript API
UDF.expireAccruals(purseId, purseName, availableBalance, lastActivityDate, pointsToExpire,
evaluateExpiredPoints, callback)
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2000 | Please provide required parameter %s in ExpireAccruals action | Required parameters (purse, or lastActivityDate/availableBalance when Evaluate Expired Points is false) are missing. |
| 2018 | Purse not found | Reported if the provided purse policy (or name when Variable) doesn't match a purse on the member. |
| 2134 | Activity failed in ExpireAccruals action due to data mismatch. | Reported when the member's current lastActivityDate or availBalance doesn't match the provided snapshot (only when Evaluate Expired Points is false). |
| 2135 | Activity failed in ExpireAccruals action due to awaiting accrual. | Reported when the purse has an accrual awaiting processing (only when Evaluate Expired Points is true). |
| 2136 | Activity failed in ExpireAccruals action due to pending redemption. | Reported when a redemption is in progress (only when Evaluate Expired Points is true). |
| 2137 | Cannot proceed with ExpireAccruals as another expiration is in progress. | Reported when the purse already has an in-progress expiration that hasn't been resolved. |
| 2138 | The points to be Expired from purse %s are invalid. | Reported when Points to Expire is not a valid number (only when Evaluate Expired Points is false). |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Additional Considerations
- Validates the purse exists before expiring balance.
- The
Purse Nameparameter is only used when the policy is set toVariable. - When
Evaluate Expired Pointsis true, the action recalculates the expired points at execution time and ignores the suppliedavailableBalance,lastActivityDate, andpointsToExpireafter the snapshot check passes. - When
Evaluate Expired Pointsis false, the action requires the suppliedlastActivityDateandavailableBalanceto exactly match the current member state — otherwise it fails with code 2134. - If
pointsToExpireis 0 andEvaluate Expired Pointsis false, the action is a no-op. - After the purse policy's period close date, the operation is a no-op (returns the purse unchanged) and only logs an info message.
Escrow Activity
Escrow Activity¶
Description
The action is used to escrow points from a previous activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| External Txn Id | String | Text | External transaction ID of the activity to escrow |
| Transaction Id | String | Text | Transaction ID of the activity to escrow |
| Purse | String | Dropdown | Select the purse policy to escrow points from |
| Purse Name | String | Text | Optional. Name of the purse when using Variable purse policy |
| Value | String | Text | Value to escrow. Examples: 10, *0.5, +12 |
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2000 | Please provide required parameters in EscrowAcitivty action | Required parameters (pursePolicy, value, and either txnId or externalTxnId; purseName when policy is Variable) are missing. |
| 2000 | No processed activity found with given extTxnId/activityId %s in Escrow Activity action | The referenced activity doesn't exist, or exists but is in Error/Cancelled status. |
| 2018 | Purse not found | The provided purse policy (or name when Variable) doesn't match a purse on the member. |
| 1730 | Invalid activity ID %s passed | Reported if the transaction ID isn't a valid ObjectId. |
| 2084 | Accrual escrow failed | Reported if the downstream purse.escrowActivity operation fails. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Additional Considerations
- At least one of
External Txn IdorTransaction Idmust be provided. - The
Purse Nameparameter is only valid when the policy is set toVariable. - The referenced activity must exist on the member (or in
ActivityHistory) and must not be inErrororCancelledstatus. - After the purse policy's period close date, the operation is a no-op (returns an empty array) and only logs an info message.
Transfer In
Transfer In¶
The Transfer In rule action transfers points from a transfer member to the context member.
Context Member
The context member refers to the member to whom the activity is being posted. This member receives the points transferred from another member.Transfer Member
The transfer member is dynamically loaded based on the Lookup Field provided in the rule action. This member is the source of the points that are getting transferred.Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Source Member _id or LoyaltyId | String | Text | Enter the member identifier (member_id or loyaltyid) to fetch the transfer member. |
| Purse Name | String | Dropdown | Select the purse to use. For variable purse names, choose "Variable" and specify the field. |
| Points | Number | Integer | Number of points to transfer. Must be a positive, whole number. |
| Activity Payload | Object | JSON | Overrides the activity payload sent by default through this action for the transfer member. |
| Accounting Type | String | Normal/Non-Revenue | Categorizes the earn. Typically, non-revenue earn is given for non-purchase activities. |
| Expiration Date | Date/Time | JS Date | Expiration date for points. Defaults to the Purse Policy setting. |
| Escrow Date | Date/Time | JS Date | Escrow date for points. Defaults to the Purse Policy setting. |
Execution Details
Context Member
The same activity is used to create the accrual using the points provided in thePoints parameter.
Transfer Member Activity
The transfer members are fetched using theLookup Field parameter. A new activity is created for the transfer member with the following payload:
{
"type": "Transfer Out",
"date": context.activity.utcDate || new Date(),
"currencyCode": context.activity.currencyCode,
"memberID": transferMember._id,
"originalMemberID": transferMember._id,
"srcChannelID": context.activity.srcChannelID,
"srcChannelType": context.activity.srcChannelType,
"value": context.activity.value,
"status": "Processed",
"result": {
"data": {
"purses": [
{
"name": "<Purse Name>",
"prev": "<Balance before this action execution>",
"prevAvail": "<Available Balance before this action execution>",
"new": "<Balance after this action execution>",
"newAvail": "<Available Balance after this action execution>"
}
]
}
}
}
JavaScript API
UDF.transferIn(lookupValue, policyId, purseName, points, activityPayload,
accountingType, expiration, escrowDate, callback)
Events Triggered
Generates the L2 AddPointsEvent on the context member and the L2 RedeemPointsEvent on the source (transfer) member.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | Please provide a valid Member ID or Loyalty ID | lookupValue is missing. |
| 4002 | No member found with memberId "%s" in program "%s" | The provided ObjectId doesn't match a member in the current program. |
| 4002 | No member found with loyaltyID "%s" in program "%s" | The provided loyalty ID doesn't resolve to a member in the current program. |
| 2145 | The target member must not be same as the source member | The transfer member resolved to the context member. |
| 2040 | Cannot find purse in member with _id %s | The source member doesn't have a purse for the given policy ID (or name when Variable). |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | The source member doesn't have enough points to redeem. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Additional Considerations
- If
pointsis 0, the action is a no-op (returns an empty array). - The two leg activities (redemption on the source member, accrual on the context member) are linked via
data.transferToActivityId/data.transferFromActivityId. - The Activity Payload override is merged on top of the generated source activity; it cannot replace the
_id,memberID,originalMemberID,program,status,value,locationId, orresultfields, which the action sets after merging.
Transfer Out
Transfer Out¶
The Transfer Out rule action transfers points from the context member to a transfer member.
Context Member
The context member refers to the member to whom the activity is being posted. This member gives the points to another member.Transfer Member
The transfer member is dynamically loaded based on the Lookup Field provided in the rule action. This member is the recipient of the transferred points.Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Target Member _id or LoyaltyId | String | Text | Enter the member identifier (member_id or loyaltyid) to fetch the transfer member. |
| Purse Name | String | Dropdown | Select the purse to use. For variable purse names, choose "Variable" and specify in the field. |
| Points | Number | Integer | Number of points to transfer. Must be a positive, whole number. |
| Activity Payload | Object | JSON | Overrides the activity payload sent by default through this action for the transfer member. |
| Accounting Type | String | Normal/Non-Revenue | Categorizes the earn. Typically, non-revenue earn is given for non-purchase activities. |
| Expiration Date | Date/Time | JS Date | Expiration date for points. Defaults to the Purse Policy setting. |
| Escrow Date | Date/Time | JS Date | Escrow date for points. Defaults to the Purse Policy setting. |
Execution Details
Context Member
The same activity is used to create the redemption using the points provided in thePoints parameter.
Transfer Member Activity
The transfer member is fetched using theLookup Field parameter. A new activity is created for the transfer member with the following payload:
{
"type": "Transfer In",
"date": context.activity.utcDate || new Date(),
"currencyCode": context.activity.currencyCode,
"memberID": transferMember._id,
"originalMemberID": transferMember._id,
"srcChannelID": context.activity.srcChannelID,
"srcChannelType": context.activity.srcChannelType,
"value": context.activity.value,
"status": "Processed",
"result": {
"data": {
"purses": [
{
"name": "<Purse Name>",
"prev": "<Balance before this action execution>",
"prevAvail": "<Available Balance before this action execution>",
"new": "<Balance after this action execution>",
"newAvail": "<Available Balance after this action execution>"
}
]
}
}
}
JavaScript API
UDF.transferOut(lookupValue, policyId, purseName, points, activityPayload,
accountingType, expiration, escrowDate, callback)
Events Triggered
Generates the L2 RedeemPointsEvent on the context member and the L2 AddPointsEvent on the target (transfer) member.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4002 | Please provide a valid Member ID or Loyalty ID | lookupValue is missing. |
| 4002 | No member found with memberId "%s" in program "%s" | The provided ObjectId doesn't match a member in the current program. |
| 4002 | No member found with loyaltyID "%s" in program "%s" | The provided loyalty ID doesn't resolve to a member in the current program. |
| 2145 | The target member must not be same as the source member | The target member resolved to the context member. |
| 2040 | Cannot find purse in member with _id %s | The target member doesn't have a purse for the given policy ID (or name when Variable). |
| 2019 | Failed to redeem %d points from purse %s because it has only %d points available | The context member doesn't have enough points to redeem. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Additional Considerations
- If
pointsis 0, the action is a no-op (returns an empty array). - The two leg activities (redemption on the context member, accrual on the target member) are linked via
data.transferToActivityId/data.transferFromActivityId. - The Activity Payload override is merged on top of the generated target activity; it cannot replace the
_id,memberID,originalMemberID,program,status,value,locationId, orresultfields, which the action sets after merging.
Transfer Accruals
Transfer Accruals¶
The Transfer Accruals rule action transfers usable accruals from the source member to a target member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Purse Name | String | Dropdown | Select the purse to use. For variable purse names, choose "Variable" and specify in the field. |
| Target Member _id or LoyaltyId | String | Text | Enter the member identifier (member_id or loyaltyid) to fetch the target member. |
| Activity Payload | Object | JSON | Overrides the activity payload sent by default through this action for the target member. |
Execution Details
Source Member
- Retrieve usable accruals of the source member(contex member).
- Calculates the total available points from usable accruals to transfer.
- Creates a single packaged redemption transaction with the total available points to mark existing accruals as used.
Target Member
- Duplicates the source member accruals to the target member to ensure that the earn and expiration dates are accurately replicated.
- Updates the target member’s purse by adding the transferred points.
- Create a new activity on the target member, with type Transfer Accruals.
{
"type": "Transfer Accruals",
"date": context.activity.utcDate || new Date(),
"currencyCode": context.activity.currencyCode,
"memberID": targetMember._id,
"originalMemberID": targetMember._id,
"srcChannelID": context.activity.srcChannelID,
"srcChannelType": context.activity.srcChannelType,
"value": context.activity.value,
"status": "Processed",
"result": {
"data": {}
},
"_internal": {
"primaryActivityId": context.activity._id
}
}
JavaScript API
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1847 | %s member %s is being merged or unmerged. Please retry later. | The source or target member has mergePendingFlag or unMergePendingFlag set. |
| 1848 | Purse name should not be empty. | Variable is selected without supplying a Purse Name. |
| 1849 | Source member %s has no accruals to transfer. | The source purse has zero or negative available balance. |
| 1852 | Source member %s has pending transfer accruals. | A previous transfer on the source purse is still in progress and hasn't been resolved. |
| 2040 | Member %s has no purse to add or redeem points. | Either source or target member is missing the purse (matched by name or policy ID). |
| 2145 | The target member must not be same as the source member. | The target member resolved to the context member. |
| 4002 | No member found with memberId "%s" in program "%s" — or — No member found with loyaltyID "%s" in program "%s" | Target member can't be resolved in the current program. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the purse policy. |
Vest Escrow Points
Vest Escrow Points¶
Description
Vests previously-escrowed accruals from a referenced activity. The action finds all accruals on the member created by that activity that haven't yet been vested, then converts them into available balance and records vesting metadata.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Activity ID | String | Text | The activity to vest accruals from. Defaults to looking the value up as an externalTxnId. Prefix the value with _id: (for example _id:507f1f77bcf86cd799439011) to look it up as a Mongo _id instead. |
JavaScript API
Outputs
Returns the array of vested accruals (empty when there are no eligible escrowed accruals). The member and activity are updated when the rule flow completes.
Events Triggered
The vesting routine generates the underlying purse update events for each affected purse.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2000 | Please provide required parameters in Vest Escrow Points action | activityId is missing. |
| 1730 | Invalid activity ID %s passed | The _id:-prefixed value isn't a valid ObjectId. |
| 2000 | No processed activity found with given extTxnId/activityId %s in Vest Escrow Points action | The referenced activity doesn't exist (in the member's activities or in ActivityHistory), or is in Error/Cancelled status. |
Additional Considerations
- The action searches first in the member's recent activities, then in the activity log.
- Accruals that have already been vested are skipped.
- The escrow vest date defaults to the current activity's date.
Rewards¶
Give Reward
Give Reward¶
Description
The action is used to add a reward to a member based on a reward policy. The reward can be configured with a custom code, usage limits, and expiration date. The reward's configuration is determined by the specified reward policy.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward | String | Dropdown | Select the reward policy to use. |
| Reward Code | String | Text | Optional. Custom code for the reward. If not provided, a UUID is generated. |
| Reward Counter | Number | Integer | Optional. Number of uses allowed. Defaults to policy's numUses value. |
| Check Limit | Boolean | Boolean | Optional. Whether to enforce reward limits. Defaults to true. |
| Expiration Date | Date/Time | JS Date | Optional. When the reward expires. If not provided, calculated from policy settings. |
Outputs
Returns the created reward object.
JavaScript API
Events Triggered
- Generates L1 ObjectInsertEvent when creating new reward
- Generates L2 AddRewardEvent when reward is added to member
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 3001 | Reward policy with "%s" "%s" not found while adding reward to member with unique id "%s" | Reported if no matching reward policy is found. |
| 1611 | Reward Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date (unless the allowFutureEffective special flag is set). |
| 1684 | Reward does not belong to member program | Reported if the reward isn't defined on the program to which the member belongs. |
| 1680 | Reward cannot be added for member %s with status %s | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s | Reported if the reward policy has expired. |
| 2049 | No more available redemptions for reward "%s" | Reported when policy.availableRedemptions <= 0. If checkLimit is false, this error is logged and swallowed (the action returns an empty array). |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- If checkLimit is false, reward limit validation errors are logged but not thrown
- If no rewardCode is provided, a UUID is automatically generated
- If no expirationDate is provided, calculated based on policy's expirationHours and expirationSnapTo settings
- If policy.availableRedemptions <= 0, throws error
- Reward's usesLeft defaults to policy.numUses if not specified
- Reward's upc defaults to policy.upc if not specified
- Validates member status against policy.applicableMemberStatus if configured
- Validates member program matches policy program
- Validates policy effectiveDate and expirationDate
- Automatically sets reward type to 'Reward'
- Sets reward name from policy name
- If special flag 'allowFutureEffective' is enabled, policy effective date validation is skipped
- If special flag 'ignoreDoubleApply' is enabled, uses left validation is skipped
- If special flag 'ignoreUsesLeft' is enabled, uses left validation is skipped
Give Specific Reward
Give Specific Reward¶
Description
The action is used to give a specific reward to a member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Object | Object | Text | Object containing reward details. See the Reward Structure for details on the object structure. |
| Check Limit | Boolean | Text | Optional. Whether to check reward limits. Defaults to true |
| Reward Counter | Number | Text | Optional. Counter for the reward |
JavaScript API
Events Triggered
- Generates L2 AddRewardEvent when reward is added
- Generates L1 ObjectInsertEvent when creating new reward
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 3001 | Reward policy with "%s" "%s" not found while adding reward to member with unique id "%s" | Reported if no matching reward policy is found (matched by name). |
| 1611 | Reward Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date. |
| 1684 | Reward does not belong to member program | Reported if the reward isn't defined on the program to which the member belongs. |
| 1680 | Reward cannot be added for member %s with status %s | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s | Reported if the reward policy has expired. |
| 2049 | No more available redemptions for reward "%s" | Reported when policy.availableRedemptions <= 0. If checkLimit is false, this error is logged and swallowed. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- The
Reward Objectparameter can be a single reward object or an array of reward objects. - Each reward object must include
name(the action setslookupFieldtonameandlookupValueto the suppliedname). - If the action receives multiple reward objects with the same
code, every duplicate after the first is replaced by a freshly generated UUID. - The action sets
member,program, andorgon each reward object before invokingmember.addSpecificReward. - When
checkLimitisfalse, error 2049 (no more redemptions) is logged and swallowed; other errors still propagate. rewardCounterdefaults to 1 when omitted.
Give Reward by Name
Give Reward by Name¶
Description
The action is used to give a reward to a member by name.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Name | String/Array | Text | The name of the reward policy (or an array of names) to give. |
| Reward Code | String/Array | Text | Optional. Code for the reward (or array, paired by index with Reward Name). If fewer codes than names are supplied, missing entries are filled with generated UUIDs. |
| Reward Counter | Number | Integer | Number of uses allowed on the issued reward. |
| Check Limit | Boolean | true/false | Optional. Whether to enforce reward-limit checks. Defaults to true. |
| Expiration Date | Date/Time | JS Date | Optional. Expiration date for the reward. Calculated from the policy when omitted. |
JavaScript API
Events Triggered
- Generates L1 ObjectInsertEvent when creating new reward
- Generates L2 AddRewardEvent when reward is added
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 3001 | Reward policy with "name" "%s" not found while adding reward to member with unique id "%s" | Reported if no matching reward policy is found by name. |
| 1611 | Reward Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date. |
| 1684 | Reward does not belong to member program | Reported if the reward isn't defined on the program to which the member belongs. |
| 1680 | Reward cannot be added for member %s with status %s | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s | Reported if the reward policy has expired. |
| 2049 | No more available redemptions for reward "%s" | Reported when policy.availableRedemptions <= 0. If checkLimit is false, this error is logged and swallowed for that reward only (other names in the same call continue). |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- Both
Reward NameandReward Codemay be supplied as arrays; rewards are issued in series, one per name. The action returns a flat array of issued rewards. - When
Reward Codehas fewer entries thanReward Name, missing positions are filled with generated UUIDs. - When
Check Limitis false, only error 2049 (no more redemptions) is suppressed; other validation errors still propagate.
Give Reward by UPC
Give Reward by UPC¶
Description
The action is used to give a reward to a member using UPC code.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Policy ID | String | Text | ID of the reward policy |
| UPC | String | Text | UPC code for the reward |
| Number of Uses | Number | Text | Number of times the reward can be used |
| Reward Counter | Number | Text | Counter for the reward |
| External Fields | Object | Text | Optional. Additional fields to add to the reward |
| Expiration Date | Date | Text | Optional. Expiration date for the reward |
JavaScript API
Events Triggered
- Generates L1 ObjectInsertEvent when creating new reward
- Generates L2 AddRewardEvent when reward is added
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 3001 | Reward policy with "_id" "%s" not found while adding reward to member with unique id "%s" | Reported if no matching reward policy is found by _id. |
| 1611 | Reward Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date. |
| 1684 | Reward does not belong to member program | Reported if the reward isn't defined on the program to which the member belongs. |
| 1680 | Reward cannot be added for member %s with status %s | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s | Reported if the reward policy has expired. |
| 2049 | No more available redemptions for reward "%s" | Reported when policy.availableRedemptions <= 0. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- Unlike most other reward-issuing actions, this action does not accept a
checkLimitparameter — limit errors always propagate. - The supplied
External Fieldsobject is passed through to the reward as-is. - The
Number of Usesparameter setsnoOfUseson the reward (corresponds tousesLefton the resulting member reward).
Cancel Reward
Cancel Reward¶
Description
The action is used to cancel a reward by its code.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Code | String | Text | Code of the reward to cancel |
| Allow Expired | Boolean | Text | Optional. Whether to allow canceling expired rewards |
| Allow Used | Boolean | Text | Optional. Whether to allow canceling used rewards |
JavaScript API
Events Triggered
- Generates L2 RewardReversalEvent when reward is cancelled
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2024 | Reward with code "%s" not found | Reported if no reward with that code exists on the member. |
| 2026 | Reward with code "%s" expired | Reported if the reward has expired and allowExpired is false. |
| 2027 | Reward with code "%s" already used | Reported if the reward has been used (usesLeft <= 0) and allowUsed is false. |
| 2083 | Can not cancel locked reward | Reported by the underlying cancel-transaction path when the reward is currently locked. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward. |
Additional Considerations
- Validates reward exists before canceling.
- Checks reward expiration status if
allowExpiredis false (string'true'or booleantrueenables override). - Checks reward usage status if
allowUsedis false (string'true'or booleantrueenables override). - Cancellation is implemented by reversing the activity that issued the reward, via
member.cancelTransaction. Reward limit counters and other side effects of the original activity are reversed.
Lock Reward
Lock Reward¶
Description
The action is used to lock a reward until a specified date, preventing it from being used until after that date.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Code | String | Text | Code of the reward to lock |
| Locked Till | Date | Text | Date until which the reward is locked |
| Transaction ID | String | Text | Optional. ID to track this lock operation |
JavaScript API
lookupField is the reward field to match against (typically code) and lookupValues is the value (or comma-separated values / array) to match. The rule-builder UI populates lookupField as code and uses the entered Reward Code as lookupValues.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2073 | Lookup field is required / Lookup value is required | lookupField or lookupValues is missing or empty. |
| 2074 | Please provide valid locked till date | The lockedTill value isn't a valid date. |
| 2119 | Please provide a valid lock transaction id | lockTxnId is provided but isn't a non-empty string. |
| 4032 | Locked till is not allowed to be less than activity date for action "lockReward" | lockedTill is earlier than the activity date. |
| 2041 | Cannot find reward with code %s | The specified reward code wasn't found on the member. |
| 2071 | Cannot use cancelled reward "%s" with code "%s" | Cannot lock a cancelled reward. |
| 2026 | Failed to use reward "%s" with code "%s". It has already expired on %s | Cannot lock an expired reward. |
| 2025 | Failed to use reward "%s" with code "%s". It comes into effect on %s | Cannot lock a reward that's not yet effective. |
| 2076 | Lockable matching reward not found | No reward matched the supplied lookupField/lookupValues is in a lockable state. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward. |
Additional Considerations
- Validates reward exists and belongs to member.
- Locked till date must be on or after the activity date.
- Can't lock cancelled rewards.
- Can't lock expired rewards.
- Can't lock rewards that aren't yet effective.
- Transaction ID must be valid if provided.
Unlock Reward
Unlock Reward¶
Description
The action is used to unlock a previously locked reward.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for looking up the reward |
| Lookup Value | String | Text | Value to match in the lookup field |
| Lock Transaction ID | String | Text | Transaction ID used when locking |
JavaScript API
lockedTill is unused for unlock and is typically passed as null or omitted. The rule-builder UI sends code as lookupField and the entered reward code as lookupValues.
Events Triggered
- Generates L2 UnlockRewardEvent when reward is unlocked
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2073 | Please provide required parameters in Unlock Reward action | Required parameters are missing |
| 2074 | Please provide valid locked till date | The lockedTill date parameter is invalid |
| 2076 | No lockable matching reward found | No matching reward found |
| 2077 | Locked till date cannot be updated since reward %s with code %s is cancelled | Can't unlock a cancelled reward |
| 2078 | Locked till date cannot be updated since reward %s with code %s is already expired on %s | Can't unlock an expired reward |
| 2117 | Locked till date cannot be updated since reward "%s" with code "%s" will come into effective on %s | Can't unlock a reward that's not yet effective |
| 2119 | Invalid lock transaction id | The provided lock transaction ID is invalid |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward |
Additional Considerations
- Validates reward exists and belongs to member.
- Validates reward isn't cancelled, expired, or not yet effective.
- Lock transaction ID must match the one used when locking.
- Updates reward's locked till date to null.
- Returns if the reward is already unlocked.
- Can't unlock rewards that have been used.
Lock Recent Reward by Type
Lock Recent Reward By Type¶
Description
The action is used to lock the most recently issued reward of a specific type until a specified date.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Type | String | Text | Type/Policy ID of the reward to lock |
| Locked Till | Date | Text | Date until which the reward is locked |
| Options | Object | Text | Optional. Additional options for locking |
JavaScript API
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2073 | Please provide required parameters in Lock Recent Reward By Type action | Required parameters are missing |
| 2074 | Please provide valid locked till date | The lockedTill date parameter is invalid or earlier than the activity date |
| 2076 | No lockable matching reward found | No reward found matching the specified type |
| 2071 | Cannot use cancelled reward "%s" with code "%s" | can't lock a cancelled reward |
| 2026 | Failed to use reward "%s" with code "%s". It has already expired on %s | can't lock an expired reward |
| 2025 | Failed to use reward "%s" with code "%s". It will come into effective on %s | can't lock a reward that's not yet effective |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward |
Additional Considerations
- Validates reward type is provided.
- Locked till date must be on or after the activity date.
- Can't lock cancelled rewards.
- Can't lock expired rewards.
- Can't lock rewards that aren't yet effective.
- Finds and locks the most recently issued reward matching the type.
Use Recent Reward by Type
Use Recent Reward By Type¶
Description
Uses the most recently assigned reward of the specified type. This action is used to redeem the latest reward that matches the given type.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Type | String | Dropdown | The reward policy ID (matched against policyId on the member's rewards). |
JavaScript API
Events Triggered
Generates the L2 UseRecentRewardByTypeEvent.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2044 | Usable rewards with types "%s" weren't found. | No usable reward matched the specified policy ID. |
| 2025 | Failed to use reward "%s". It comes into effect on %s | The reward isn't currently effective. |
| 2026 | Failed to use reward "%s". It has already expired on %s | The reward has expired. |
| 2027 | Failed to use reward "%s". No more uses left. | The reward has reached its maximum number of uses. |
| 2071 | Cannot use cancelled reward "%s" with code "%s". | The reward has been cancelled. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward. |
Additional Considerations
- The reward must be assigned to the member before it can be used.
- The reward must be within its effective dates.
- The reward must not have exceeded its maximum uses.
- The reward must not be cancelled.
- Only the most recently assigned reward of the specified type is used.
- The reward type is case sensitive.
- If multiple rewards of the same type exist, the most recently assigned one is used.
Use Reward by Code
Use Reward By Code¶
Description
Uses a reward by its code. This action is used to redeem a reward that was assigned to a member using a code.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Code | String | Text | The reward code to use. Must match the code of an existing reward on the member. |
JavaScript API
Events Triggered
Generates the L2 UseRewardByCodeEvent.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2041 | Cannot find reward with code %s | The reward code wasn't found on the member. |
| 2025 | Failed to use reward "%s". It comes into effect on %s | The reward isn't currently effective. |
| 2026 | Failed to use reward "%s". It has already expired on %s | The reward has expired. |
| 2027 | Failed to use reward "%s". No more uses left. | The reward has reached its maximum number of uses. |
| 2071 | Cannot use cancelled reward "%s" with code "%s". | The reward has been cancelled. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward. |
Additional Considerations
- The reward must be assigned to the member before it can be used
- The reward must be within its effective dates
- The reward must not have exceeded its maximum uses
- The reward must not be cancelled
Offers¶
Give Offer by Lookup
Give Offer by Lookup Field¶
Description
The action is used to give an offer to a member using lookup field.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field on the offer policy to match against (typically _id or name). |
| Lookup Value | String | Text | Value to match in the lookup field. |
| Offer Code | String | Text | Optional. Custom code for the offer. A UUID is generated when omitted. |
| Offer Counter | Number | Integer | Number of times the offer can be used. |
| Check Limit | Boolean | true/false | Optional. Whether to enforce limit checks. Defaults to true. |
| Expiration Date | Date/Time | JS Date | Optional. Expiration date for the offer. Calculated from the policy when omitted. |
| Future Effective | Boolean | true/false | Optional. When true, allows the offer to be issued even if the policy's effective date is after the activity date. |
JavaScript API
UDF.giveOfferByLookup(lookupField, lookupValue, offerCode, offerCounter, checkLimit, expirationDate, futureEffective, callback)
Events Triggered
- Generates L1 ObjectInsertEvent when creating new offer
- Generates L2 AddOfferEvent when offer is added
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2015 | No offer found / lookup missing | Reported when both lookupField and lookupValue are missing or empty. |
| 3001 | Reward policy with %s %s not found while adding offer to member with unique id %s. | Reported if no matching offer policy is found. |
| 1612 | Offer Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date and Future Effective is false. |
| 1684 | Offer does not belong to member program. | Reported if the offer isn't defined on the program to which the member belongs. |
| 1680 | Offer cannot be added for member %s with status %s. | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s. | The reward policy has expired. |
| 2049 | No more available redemptions for offer "%s" | The offer policy has no remaining redemptions. Suppressed when checkLimit is false. |
| 2062 | No more available budget for offer "%s" | The offer policy has no remaining budget. Suppressed when checkLimit is false. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- When
checkLimitis false, error codes 2049 and 2062 are logged and swallowed (the action returns an empty array). Other validation errors still propagate. - After a successful issue, the offer is added to the activity result.
Give Offer by Lookup with Params
Give Offer by Lookup Field With Params¶
Description
The action is used to give an offer to a member using lookup field and additional parameters.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for looking up the offer |
| Lookup Value | String | Text | Value to match in the lookup field |
| Params | Object | Text | Additional parameters for the offer |
| Offer Counter | Number | Text | Number of times the offer can be used |
| Check Limit | Boolean | Text | Optional. Whether to check offer limits. Defaults to true |
JavaScript API
UDF.giveOfferByLookupWithParams(lookupField, lookupValue, params, offerCounter, checkLimit, callback)
Events Triggered
- Generates L1 ObjectInsertEvent when creating new offer
- Generates L2 AddOfferEvent when offer is added
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2015 | No offer | Reported when both lookupField and lookupValue are missing or empty. |
| 3001 | Reward policy with %s %s not found while adding offer to member with unique id %s. | Reported if no matching offer policy is found. |
| 1612 | Offer Policy %s is not yet effective | Reported if the policy's effectiveDate is after the activity date. |
| 1684 | Offer does not belong to member program. | Reported if the offer isn't defined on the program to which the member belongs. |
| 1680 | Offer cannot be added for member %s with status %s. | Reported if the member's status isn't in policy.applicableMemberStatus. |
| 2023 | Reward Policy has already expired on %s. | The reward policy has expired. |
| 2049 | No more available redemptions for offer "%s" | Suppressed when checkLimit is false. |
| 2062 | No more available budget for offer "%s" | Suppressed when checkLimit is false. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy. |
Additional Considerations
- When
checkLimitis false, error codes 2049 and 2062 are logged and swallowed (the action returns an empty array). Other validation errors still propagate. - The
paramsobject overrides default offer fields (such as code, expiration date, custom fields).
Lock Offer
Lock Offer¶
Description
The action is used to lock an offer until a specified date.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for looking up the offer |
| Lookup Value | String | Text | Value to match in the lookup field |
| Locked Till | Date | Text | Date until which the offer is locked |
| Lock Transaction ID | String | Text | Transaction ID for the lock operation |
JavaScript API
Events Triggered
- Generates L2 LockOfferEvent when offer is locked
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2108 | Please provide lookup field and/or lookup value | Reported if required parameters are missing |
| 2109 | Please provide valid locked till date | Reported if locked till date is invalid |
| 2111 | Locked till date cannot be updated since offer with field %s and value %s does not exist for the member | Reported if no matching offer found |
| 2110 | Locked till date cannot be updated since offer %s with code %s is already used | Reported if offer is already used |
| 2112 | Locked till date cannot be updated since offer %s with code %s is cancelled | Reported if offer is cancelled |
| 2113 | Locked till date cannot be updated since offer %s with code %s is already expired | Reported if offer has expired |
| 2114 | Global offer "%s" is not lockable/unlockable | Reported if trying to lock a global offer |
| 2115 | Please provide lock transaction id | Reported if lock transaction ID is missing |
| 2116 | Please provide a valid lock transaction id | Reported if lock transaction ID is invalid |
| 2118 | Locked till date cannot be updated since offer "%s" with code "%s" will come into effective on %s | Reported if offer isn't yet effective |
| 2120 | Multi use offer "%s" is not lockable/unlockable | Reported if trying to lock a multi-use offer |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the offer |
Additional Considerations
- Validates offer exists and belongs to member.
- Validates the offer isn't already used, cancelled, or expired.
- Can't lock global offers or multi-use offers.
- Lock transaction ID is required and must be valid.
- Locked till date must be valid and on or after the activity date.
Unlock Offer
Unlock Offer¶
Description
The action is used to unlock a previously locked offer.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for looking up the offer |
| Lookup Value | String | Text | Value to match in the lookup field |
| Lock Transaction ID | String | Text | Transaction ID used when locking |
JavaScript API
Events Triggered
- Generates L2 UnlockOfferEvent when offer is unlocked
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2108 | Please provide lookup field and/or lookup value | Required parameters are missing |
| 2111 | Locked till date cannot be updated since offer with field %s and value %s doesn't exist for the member | No matching offer found |
| 2112 | Locked till date cannot be updated since offer %s with code %s is cancelled | Can't unlock a cancelled offer |
| 2113 | Locked till date cannot be updated since offer %s with code %s is already expired | Can't unlock an expired offer |
| 2114 | Global offer "%s" is not lockable/unlockable | Can't unlock a global offer |
| 2115 | Please provide lock transaction id | Lock transaction ID is missing |
| 2116 | Please provide a valid lock transaction id | Lock transaction ID is invalid |
| 2118 | Locked till date cannot be updated since offer "%s" with code "%s" comes into effect on %s | Can't unlock an offer that isn't yet effective |
| 2120 | Multi use offer "%s" is not lockable/unlockable | Can't unlock a multi-use offer |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the offer |
Additional Considerations
- Validates offer exists and belongs to member.
- Validates the reward isn't cancelled or expired and has taken effect.
- Can't unlock global offers or multi-use offers.
- Lock transaction ID is required and must be valid.
- Must match the transaction ID used when locking.
- Updates offer's locked till date to null.
Use Offer by Code
Use Offer By Code¶
Description
Uses an offer by its code. This action is used to redeem an offer that was assigned to a member using a code.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Offer Code | String | Text | The offer code to use. Must match the code of an existing offer on the member. |
Outputs
Adds the used offer to Context.result.data.offersUsed.
JavaScript API
Events Triggered
Generates the L2 UseOfferEvent.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2011 | Cannot find offer with code %s | The offer code wasn't found on the member. |
| 2012 | Offer "%s" with code "%s" is not yet effective | The offer isn't currently effective. |
| 2013 | Offer "%s" with code "%s" has expired on %s | The offer has expired. |
| 2014 | Failed to use offer "%s". No more uses left. | The offer has reached its maximum number of uses. |
| 2072 | Cannot use cancelled offer "%s" with code "%s" | The offer has been cancelled. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the offer. |
Additional Considerations
- The offer must be assigned to the member before it can be used
- The offer must be within its effective dates
- The offer must not have exceeded its maximum uses
- The offer must not be cancelled
Apply Offers
Apply Offers¶
Description
The action is used to apply the best offers to the current activity based on the activity's best offers list.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Ignore Missing | Object | JSON | Configuration for whether to raise errors for missing offers/rewards. Defaults to: { ignoreGlobalOffer: false, ignoreOffer: false, ignoreReward: false } |
JavaScript API
Events Triggered
- Generates L2 UseOfferByCodeEvent for each offer applied
- Generates L2 UseRewardByCodeEvent for each reward applied
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2011 | Offer not found | Reported if an offer can't be found |
| 2012 | Offer not effective | Reported if an offer's effective date is after the activity date |
| 2013 | Offer expired | Reported if an offer has expired |
| 2014 | No more uses left | Reported if an offer has no remaining uses |
| 2015 | No offer | Reported if no offers are available to apply |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward policy, reward, or offer |
Additional Considerations
- Uses the activity's bestOffers list to determine which offers to apply
- If ignoreGlobalOffer is false, throws an error when global offer policies aren't found
- If ignoreOffer is false, throws an error when offer not found for member
- If ignoreReward is false, throws an error when reward not found for member
- Validates offer effective dates and expiration dates before applying
Check Offer Limits
Check Offer Limits¶
Description
The action is used to check if a member has exceeded offer or reward limits based on configured thresholds.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Entity | String | Dropdown | Type of entity to check limits for. Select from LimitPolicyType enum |
| Policy Filter | Object | JSON | Optional. Filter to select specific policies. Defaults to {} |
| Limits | Object | JSON | Optional. Limit thresholds to check. Example: {perOffer: 10, perMonth: 5, perWeek: 2, perDay: 1} |
| Calendar | Boolean | Boolean | Whether to use calendar months/weeks vs rolling periods |
Outputs
Sets Context.limitExceeded to true if any limit is exceeded, false otherwise.
JavaScript API
Events Triggered
No events are generated by this action.
Possible Errors
This action does not throw rule-engine validation errors. Any error is a propagated database error from MongoDB.
Additional Considerations
- Supports
day,week, andmonthlimits supplied as keys on thelimitsobject. - The
entityTypeis normalized to eitherRewardorOffer(any other value falls back toOffer). - If
limitsis empty or missing, the action returns without computing anything (andContext.limitExceededremainsfalse). - Week boundaries follow the program's
weekStartDaysetting only whenCalendaris true. - Calendar mode uses fixed month/week boundaries; non-calendar mode uses rolling periods ending at the activity date.
- The action counts both transient member records (rewards/offers on the in-memory member) and stored records.
Update Member Offer With Params
Update Member Offer With Params¶
Description
The action is used to apply the provided lookups and offer filter to identify relevant member offers and updates their attributes.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Optional. The field to query on member offers |
| Lookup Value | String | Text | Optional. Values to be used for lookup |
| Offer Filter | Object | JSON | Optional. Additional filters to apply to the query |
| Offer Object | Object | JSON | A JSON string containing the attributes to be updated |
Outputs
The updates are applied to each member offer record filtered using the provided lookup fields and values. If an offer filter is provided and its key matches a lookup field, the filter conditions are combined with the existing lookups; otherwise, the filter is applied alongside the existing criteria.
JavaScript API
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2108 | Please provide either a valid lookup field with its corresponding lookup value or a non-empty, valid offer filter | Required parameters are missing |
| 2108 | Lookup values are missing for the provided lookup fields | Reported when a lookup value is missing for a specified lookup field |
| 2126 | The number of lookup fields must match the number of lookup values | Reported when the count of lookup fields and lookup values don't align |
| 2127 | Invalid format for lookupValues. Please ensure it follows a proper JSON-like structure | Reported when the lookupValues are provided in an invalid JSON format |
| 4011 | The date provided %s for the %s field isn't in a valid format | Reported when the date format is invalid |
| 2128 | The effectiveDate for offer %s can't be updated because it falls after the offer's expirationDate %s | Reported when setting an offer's effectiveDate later than its expirationDate |
| 2129 | The expiresOn offer, %s, can't be updated because it occurs before the offer's effectiveDate %s | Reported when setting an offer's expiration date earlier than its effectiveDate |
| 4034 | Please provide a valid "Offer update object" | Reported when the provided Offer update object isn't valid |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the offer |
Additional Considerations
- The offer must be assigned to the member before its attributes can be updated.
- Returns if the offer matching the filters isn't found.
- Sets updatedAt and updatedBy fields automatically.
- Updates the attributes of the member's offer based on the applied filters.
Resolve Best Offer Policies
Resolve Best Offer Policies¶
Description
The action is used to resolve and populate offer policies corresponding to best offers.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Object | Object | JSON | Mapping of offer types to lookup field configurations |
| Context | Object | JSON | Optional. Context object to use. If not provided, uses this.context |
JavaScript API
Outputs
Updates best offers in Context.activity.bestOffers with resolved policy IDs.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2057 | Lookup field is required for Best Offer Policies action | lookupObj is empty or missing required keys. |
| 2055 | The offer policies corresponding to best offers do not exist | No policies match the lookup. |
| 2056 | The offer policies corresponding to best offers lookup values %s do not exist | Some lookup values didn't match any policies. |
Additional Considerations
- Validates lookup field is provided
- Looks up policies by the specified field
- Updates originalPolicyId and policyId in best offers
- Logs missing policies if ignoreMissing is true
- Only processes global offers that don't already have originalPolicyId
- Handles location overrides if configured
Promo Codes¶
Assign Promo Code
Assign Promo Code¶
Description
The action is used to assign a promo code from a campaign to a member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Campaign Code | String | Text | The campaign code to assign a promo code from |
JavaScript API
Events Triggered
- Generates L1 ObjectUpdateEvent
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2087 | Promo campaign with code %s not found | Reported if the promo campaign code isn't found |
| 2088 | Promo campaign with code %s expired | Reported if the promo campaign's end date is before the activity date |
| 2090 | Promo campaign with code %s not started | Reported if the promo campaign's start date is after the activity date |
Additional Considerations
- Validates campaign exists and is within its effective period
- Updates promo code status from 'New' to 'Assigned'
- Sets assignment date to current time
- Validates campaign belongs to member's program
Redeem Promo Code
Redeem Promo Code¶
Description
The action is used to redeem a promo code that has been assigned to the member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Promo Code | String | Text | Code to redeem |
JavaScript API
Outputs
Populates Context.result.data.promoCodes with array containing the redeemed promo code object.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2089 | Promo code %s to be redeemed not found | The specified promo code wasn't found or isn't assigned to the member |
| 2088 | Promo campaign with code %s expired | The promo campaign has expired |
| 2090 | Promo campaign with code %s not started | The promo campaign hasn't started yet |
Additional Considerations
- Validates promo code exists and is assigned to member
- Checks campaign start and end dates
- Updates promo code status to 'Redeemed'
- Sets redemption date to current activity date
- Updates context with redeemed code details
- Combines with any existing promo codes in context
Assign and Redeem Promo Code
Assign And Redeem Promo Code¶
Description
The action is used to assign and immediately redeem a promo code in a single operation.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Promo Code | String | Text | The promo code to assign and redeem |
JavaScript API
Events Triggered
- Generates L1 ObjectUpdateEvent
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2089 | Promo code %s to be redeemed not found | Reported if the promo code doesn't exist or isn't available |
| 2088 | Promo campaign with code %s expired | Reported if the promo campaign's end date is before the activity date |
| 2090 | Promo campaign with code %s not started | Reported if the promo campaign's start date is after the activity date |
Additional Considerations
- Validates promo code exists and is in 'New' status
- Updates promo code status directly from 'New' to 'Redeemed'
- Sets both assignment and redemption dates to current time
- Validates campaign belongs to member's program
Activities & Events¶
Lookup Activities
Lookup Activities¶
Description
The action is used to lookup and populate activities for the current member within a specified date range.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| From Date | Date | Text | Optional. Start date for activity lookup. Defaults to start of current day |
| Limit | Number | Integer | Optional. Maximum number of activities to return |
| Status | String | Text | Optional. Filter by activity statuses. Comma-separated list |
| Type | String | Text | Optional. Filter by activity type |
JavaScript API
Outputs
Populates Context.member.activities with an array of activity objects.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | The From Date is not in a valid format | Invalid date format |
| 4037 | The From date is not within the allowed range of 1900 to 3999 | Invalid date range |
Additional Considerations
- If fromDate isn't provided, defaults to start of current day.
- Activities are filtered by member ID and original member ID (unless disOriginalMemIdHisLookup is enabled).
- Activities are filtered to be between fromDate and current activity date.
- Respects program setting disOriginalMemIdHisLookup to control whether to lookup by original member ID.
- Status parameter can be a comma-separated list of statuses to filter by.
Lookup Activity by ID
Lookup Activity By ID¶
Description
The action is used to lookup and populate a specific activity by its ID.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Activity ID | String | Text | ID of the activity to lookup |
JavaScript API
Outputs
Populates Context.member.activities array with the found activity object.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns immediately if activity ID is invalid or not provided
- Returns if activity isn't found
Lookup Activity by Params
Lookup Activity By Params¶
Description
The action is used to lookup and populate activities matching specified parameters.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Comma-separated list of fields to match on |
| Lookup Value | String | Text | Comma-separated list of values corresponding to lookup fields |
JavaScript API
Outputs
Populates Context.member.activities with matching activity objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns immediately if the lookup field or value isn't provided
- Returns if no matching activities are found
- Supports multiple lookup fields and values as comma-separated lists
- Values must match in order with their corresponding lookup fields
Cancel Transaction
Cancel Transaction¶
Description
The action is used to cancel a previous transaction by either its activity ID or external transaction ID.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for finding the transaction. Either '_id' or 'externalTxnId'. Defaults to 'externalTxnId' |
| Value | String | Text | Value of the lookup field to identify the transaction to cancel |
JavaScript API
Events Triggered
- Generates L2 CancelActivityEvent when transaction is cancelled
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1730 | Invalid activity ID %s passed | Reported when lookupField is _id and the supplied value isn't a valid ObjectId. |
| 1731 | Invalid lookup field | Reported if lookupField isn't _id or externalTxnId. |
| 2000 | No processed activity found with given extTxnId/activityId %s | The referenced activity doesn't exist or is in Error/Cancelled status (propagated from member.cancelTransaction). |
Additional Considerations
- Reverses all point transactions from the original activity
- Cancels any rewards or offers that were issued
- Updates the original activity status to indicate cancellation
- Maintains audit trail of the cancellation
Create Metric Event
Create Metric Event¶
Description
This action is deprecated and no longer supported. Use Update Member Aggregate instead, which writes to the same aggregate pipeline using a typed AggregatePolicy.
Any rule that fires this action returns error 4049 ('Create Metric Event' action has been deprecated and is no longer supported.).
Parameters
None — the action is rejected before its parameters are evaluated.
JavaScript API
The corresponding UDF.createAggEvent function is also deprecated.
Events Triggered
None.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4049 | 'Create Metric Event' action has been deprecated and is no longer supported. | Always returned when this action fires. |
Additional Considerations
- Existing rules that reference this action should be migrated to Update Member Aggregate. The replacement requires the metric to exist as an
AggregatePolicy(orPursePolicy) in the same program.
Generate Custom Event
Generate Custom Event¶
Description
The action is used to generate a custom event with the provided data.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Data | Object | Text | The data to include in the custom event payload |
JavaScript API
Events Triggered
- Generates L2 CustomActionEvent with the provided data as payload
Possible Errors
This action doesn't throw any errors.
Additional Considerations
- Only generates an event if
datais provided and not empty. - The event includes the current user and member as part of its header.
Lookups¶
Lookup Activity Offers
Lookup Activity Offers¶
Description
The action is used to lookup and populate offer coupons associated with the current activity.
Parameters
None. Uses the current activity context.
JavaScript API
Outputs
Populates the current activity with:
activity.coupon: The main activity coupon if activity.couponCode existsactivity.lineItems[].coupon: Individual line item coupons if lineItems[].couponCode exists
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Looks up offer coupons by their code.
- Only returns coupons that still have uses remaining.
- Sorts by expiration date when multiple matches exist.
- Attaches coupons at both the activity level and the line-item level.
- Returns if no matching coupons are found.
Lookup Activity Rewards
Lookup Activity Rewards¶
Description
The action is used to lookup and populate reward coupons associated with the current activity.
Parameters
None. Uses the current activity context.
JavaScript API
Outputs
Populates the current activity with:
activity.coupon: The main activity coupon if activity.couponCode exists and matches the Reward codeactivity.lineItems[].coupon: Individual line item coupons if lineItems[].couponCode exists and matches the Reward code
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Looks up reward coupons by their code.
- Only returns coupons that still have uses remaining.
- Sorts by expiration date when multiple matches exist.
- Attaches coupons at both the activity level and the line-item level.
- Returns if no matching coupons are found.
Lookup Applicable Offers
Lookup Applicable Offers¶
Description
The action is used to find the all applicable offers for the current activity and member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Best Offers Filter | Object | JSON | Optional. Filter criteria for offers |
| Policy Filter | Object | JSON | Optional. Additional filters to apply to the policies. |
| Line Item Exclusion Filter | Object | JSON | Optional. Filter criteria for line items |
| Options | Object | JSON | Optional. Additional options like lockTxnId |
| Populate Fields | Object | JSON | Optional. Fields to populate from policies |
JavaScript API
UDF.populateApplicableOffers(filterOfferTypes, policyFilter, lineItemFilter, options, populateFields, callback)
Populates Context.result.data.applicableOffers with array of applicable offers/rewards.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Validates all offers/rewards exist and are usable
- Checks offers/rewards cancellation status
- Verifies offers/rewards effective dates
- Validates remaining offers/rewards uses
- Handles both global and member-specific offers (wallet offers/rewards)
- Supports offer budget constraints
- Applies location overrides if configured
- Serializes line items if SPECIAL_FLAGS includes 'serializeLineItems'
Lookup Best Offers
Lookup Best Offers¶
Description
The action is used to find the best applicable offers for the current activity and member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Populate Fields | Object | JSON | Optional. Fields to populate from policies |
| Offer Filter | Object | JSON | Optional. Filter criteria for offers |
| Line Item Filter | Object | JSON | Optional. Filter criteria for line items |
| Options | Object | JSON | Optional. Additional options like lockTxnId |
| Include Applicable Offers | Boolean | Text | Optional. Whether to load all the applicable offers to given line items and put that on UDF.select('$.Context.result.data.applicableOffers). |
| Policy Filter | Object | JSON | Optional. Additional filters to apply to the policies. |
JavaScript API
Outputs
Populates Context.result.data with:
- bestOffers: Array of best applicable offers
- repricedTicket: Activity with applied discounts
- applicableOffers: Array of all applicable offers
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Validates all offers exist and are usable
- Checks offer cancellation status
- Verifies offer effective dates
- Validates remaining offer uses
- Handles both global and member-specific offers (wallet offers)
- Supports offer budget constraints
- Applies location overrides if configured
- Optimizes offer combinations for maximum discount
- Serializes line items if SPECIAL_FLAGS includes 'serializeLineItems'
Lookup Best Offer Policies
Lookup Best Offer Policies¶
Description
The action is used to lookup and populate offer policies corresponding to best offers.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Field to use for looking up policies |
| Ignore Missing | Boolean | Text | Optional. Whether to ignore missing policies |
JavaScript API
Outputs
Updates best offers in Context.activity.bestOffers with resolved policy IDs.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2057 | Lookup field is required for Best Offer Policies action | lookupField parameter is missing. |
| 2055 | The offer policies corresponding to best offers do not exist | No policies match the lookup. Only thrown when ignoreMissing is false. |
| 2056 | The offer policies corresponding to best offers lookup values %s do not exist | Some lookup values didn't match any policies. Only thrown when ignoreMissing is false. |
Additional Considerations
- Validates lookup field is provided
- Looks up policies by the specified field
- Updates originalPolicyId and policyId in best offers
- Logs missing policies if ignoreMissing is true
- Only processes global offers that don't already have originalPolicyId
Lookup Contextual Reward Policies
Lookup Contextual Reward Policies¶
Description
The action is used to find applicable reward policies based on the current activity context, optionally filtered by type and balance requirements.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Optional. Field to filter policies by |
| Lookup Value | String | Text | Optional. Value to match against lookup field |
| Policy Filter | Object | JSON | Optional. Additional filter criteria for policies |
| Line Item Exclusion Filter | Object | JSON | Optional. Filter to exclude certain line items |
| Balance | Number | Text | Optional. Points balance to check against policy costs |
| Max Policies | Number | Integer | Optional. Maximum number of policies to return |
JavaScript API
UDF.promptApplicablePolicies(lookupField, lookupValue, policyFilter, lineItemExclusionFilter, balance, maxPolicies, callback)
Outputs
Populates Context.result.data.applicablePolicies with array of:
- policy: The reward policy object
- discountAmount: Maximum possible discount for this policy
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1807 | Balance should be a number in Lookup Contextual Reward Policies action | Balance parameter must be numeric. |
| 1807 | MaxPolicies should be a number in Lookup Contextual Reward Policies action | MaxPolicies parameter must be numeric. |
Additional Considerations
- Validates numeric parameters (balance, maxPolicies)
- Filters policies by:
- Available redemptions > 0
- Expiration date >= activity date
- Budget > 0 for offers
- Cost <= balance (if balance provided)
- Applies location overrides if configured
- Calculates maximum possible discount for each policy
- Sorts results by discount amount (descending)
- Returns top N results if maxPolicies specified
- Handles both rewards and offers with budget constraints
Lookup Eligible Offers
Lookup Eligible Offers¶
Description
The action is used to find all eligible offers for the current activity and member based on policy and line item filters.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Policy Filter | Object | JSON | Optional. Filter criteria for reward policies |
| Offer Filter | Object | JSON | Optional. Filter criteria for offers (filterOffer, filterReward, filterGlobalOffer) |
| Line Item Filter | Object | JSON | Optional. Filter to exclude certain line items |
JavaScript API
Outputs
Populates Context with:
eligibleOffers: Array of eligible offerseligibleRewardPolicies: Array of eligible reward policies with applicable product lines
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Filters offers based on:
- Member's program
- Location overrides if configured
- Policy criteria if provided
- Line item criteria if provided
- Calculates applicable product lines for each reward policy
- Handles different discount types:
- Ticket
- Mix and Match
- Combo
- ComboList
- Supports filtering by:
- Regular offers
- Reward offers
- Global offers
- Logs debug information about policy filtering and location overrides
Lookup Enums
Lookup Enums¶
Description
The action is used to lookup and populate enums of specified types.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Enum Types | String | Text | Optional. Comma-separated list of enum types to lookup |
JavaScript API
Outputs
Populates Context.activityEnums with array of matching enum objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- If no enum types provided, logs debug message and returns
- Filters enums by language 'en'
- Combines with any existing enums in
Context.activityEnums - Uses cached enum data when available
- Returns all enums if no types specified
- Deduplicates enum values using Set
Lookup Linked Member Offers
Lookup Linked Member Offers¶
Description
The action is used to lookup and populate offers for all members linked to the current member's account.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| From Date | Date | Text | Optional. Start date for offer lookup |
| Usable | Boolean/Object | Text | Optional. Filter for usable offers or custom filter criteria |
JavaScript API
Outputs
Populates each linked member in Context.linkedAccount.members with:
offers: Array of offer objects
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | The From Date is not in a valid format | Invalid date format |
| 4037 | The From date is not within the allowed range of 1900 to 3999 | Invalid date range |
Additional Considerations
- Filters offers by:
- Member ID from linked members array.
- From date if provided.
- Usable status (not cancelled, has uses left, not expired) if usable=true.
- Custom filter criteria if usable is an object.
- Marks all loaded offers as transitive.
- Combines offers from both database and member's transient data.
- Skips loading if linked members aren't populated.
Lookup Linked Member Rewards
Lookup Linked Member Rewards¶
Description
The action is used to lookup and populate rewards for all members linked to the current member's account.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| From Date | Date | Text | Optional. Start date for reward lookup |
| Usable | Boolean/Object | Text | Optional. Filter for usable rewards or custom filter criteria |
JavaScript API
Outputs
Populates each linked member in Context.linkedAccount.members with:
rewards: Array of reward objects
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | The From Date is not in a valid format | Invalid date format |
| 4037 | The From date is not within the allowed range of 1900 to 3999 | Invalid date range |
Additional Considerations
- Filters rewards by:
- Member ID from linked members array.
- From date if provided.
- Usable status (not cancelled, has uses left, not expired) if usable=true.
- Custom filter criteria if usable is an object.
- Marks all loaded rewards as transitive.
- Combines rewards from both database and member's transient data.
- Skips loading if linked members aren't populated.
Lookup Location
Lookup Location¶
Description
The action is used to lookup and populate location information for the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Fields | String | Text | Optional. Comma-separated list of fields to match on. If not provided, matches on srcChannelID |
JavaScript API
Outputs
Populates Context.activity with:
location: The matched location objectutcOffset: Timezone offset from location or program defaultutcDate: Activity date adjusted for timezone
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- If no lookup fields provided, matches on activity.srcChannelID.
- Uses location timezone if available, otherwise program default UTC offset.
- Sets activity.utcDate based on timezone offset.
- Handles location overrides for rules if configured.
- Returns if no matching location is found.
Lookup Member Offers
Lookup Member Offers¶
Description
The action is used to lookup and populate offers associated with the current member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| From Date | Date | Text | Optional. Start date for offer lookup |
| Usable | Boolean/Object | Text | Optional. Filter for usable offers or custom filter criteria |
JavaScript API
Outputs
Populates Context.member.offers with array of offer objects.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | The From Date is not in a valid format | Invalid date format |
| 4037 | The From Date is not within the allowed range of 1900 to 3999 | Invalid date range |
Additional Considerations
- Filters offers by:
- Member ID
- From date if provided
- Usable status (not cancelled, has uses left, not expired) if usable=true
- Custom filter criteria if usable is an object
- Marks all loaded offers as transitive
- Returns empty array if no offers found
Lookup Member Preferences
Lookup Member Preferences¶
Description
The action is used to lookup and populate preferences for the current member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Name | String | Text | Optional. Name of preference to lookup. If not provided, returns all preferences |
JavaScript API
Outputs
Populates Context.member.preferences with array of preference objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns early if preference already exists in member.preferences
- Filters preferences by:
- Member ID
- Expiration date > current date
- Preference name if provided
- Handles cancelled preferences by removing them from results
- Returns empty array if no preferences found
Lookup Member Rewards
Lookup Member Rewards¶
Description
The action is used to lookup and populate rewards associated with the current member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| From Date | Date | Text | Optional. Start date for reward lookup |
| Usable | Boolean/Object | Text | Optional. Filter for usable rewards or custom filter criteria |
JavaScript API
Outputs
Populates Context.member.rewards with array of reward objects.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4011 | The From Date is not in a valid format | Invalid date format. |
Additional Considerations
- Filters rewards by:
- Member ID
- From date if provided
- Usable status (not cancelled, has uses left, not expired) if usable=true
- Custom filter criteria if usable is an object
- Marks all loaded rewards as transitive
- Returns empty array if no rewards found
Lookup Partner
Lookup Partner¶
Description
The action is used to lookup and populate partner information for the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Partner Code | String | Text | Optional. Code of partner to lookup. If not provided, uses activity.partnerCode |
JavaScript API
Outputs
Populates Context.activity.partner with the partner object
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1669 | Rule partners not found | The specified partner code wasn't found |
Additional Considerations
- If no partner code is provided, uses
activity.partnerCode. - Returns early if no partner code is available.
- Returns if no matching partner is found.
- Supports passing a partner object directly instead of a code.
Lookup Products
Lookup Products¶
Description
The action is used to lookup and populate product information for activity line items.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Apply To | String | Text | Optional. Where to apply products ('Activity' or 'Repriced Ticket'). Defaults to 'Activity' |
| Lookup Fields | String | Text | Optional. Field to use for product lookup (for example, 'name:type'). Defaults to 'sku:itemSKU' |
JavaScript API
Outputs
Populates Context with:
activityProducts: Array of products with line numbers and quantities- Updates line items in activity or repricedTicket with product information
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2017 | Products with |
The specified products weren't found and no 'Missing Product' was defined in the Products of RCX |
| 2058 | Multiple products found with overlapping effective dates | Found products with overlapping effective dates |
Additional Considerations
- If no lookup fields provided, uses 'sku:itemSKU' as default.
- Supports productId lookup if line items have productId field.
- Validates product effective dates against activity date.
- Handles missing products by using 'Missing Product' placeholder if available.
- Combines line item data with product data.
- Supports custom lookup field mappings (for example, 'name:type') where the first field is a field in lineItem and the second is part of the Product.
- Values must match in order with their corresponding lookup fields.
Lookup Missing Products
Lookup Missing Products¶
This action resolves missing products that were previously populated as "Missing Product" by the Lookup Products action. It processes only line items with missing products and attempts to resolve them using a specified lookup field.
Parameters
This section defines the input required to execute the Lookup Missing Products action. This parameter determines the field mapping strategy used to identify and resolve missing products.
Lookup Field (String, Text): Required. Field to use for product lookup (for example, 'ext.sku:itemSKU', 'name:type'). Supports nested fields using dot notation.
JavaScript API
Outputs
After execution, this action updates the context with resolved product data. The following describes the changes that are made to the activity context and how unresolved items are handled:
- Updates line items that had missing products with resolved product information
- Updates
activityProductsarray with resolved product details - Leaves unresolved products as "Missing Product" (no errors thrown)
Events Triggered
This section outlines any system or custom events that might be triggered during the execution of this action. In this case, no events are generated.
Possible Errors
Here are the potential errors that might occur during execution, along with their descriptions and causes. This helps in debugging and ensuring proper use of the action. Note that missing products that can't be resolved don't generate errors.
| Error Code | Error Message | Description |
|---|---|---|
| 1731 | Invalid lookup field | The lookup field parameter is required but wasn't provided. |
Additional Considerations
This section outlines important behavioral details and constraints of the Lookup Missing Products action. These considerations help ensure proper usage, clarify how the action handles edge cases, and highlight its dependencies and limitations within the product resolution workflow.
- Only processes line items that currently have "Missing Product" entries.
- Supports nested field lookups using dot notation (for example, 'ext.sku:itemSKU').
- Handles partial resolution, resolves what it can find, and leaves others as missing.
- Doesn't throw errors for products that can't be found.
- Preserves already resolved products - only updates missing ones.
- Automatically extracts lookup values from missing line items.
- Supports both simple field mapping ('name') and field-to-field mapping ('name:type').
- Must be run after the Lookup Products action to have missing products to resolve.
- Validates product effective dates against activity date.
- Updates both activity.lineItems and context.activityProducts arrays consistently.
Lookup Promo Codes
Lookup Promo Codes¶
Description
The action is used to lookup and populate promo codes for the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Promo Codes | String/Array | Text | Codes to lookup |
| Load Target | Object | JSON | Optional. Target object to populate with results. If not provided, uses Context.result.data |
JavaScript API
Outputs
Populates target (or Context.result.data) with:
promoCodes: Array of promo code objects with their definitions
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| (plain Error) | Promo codes no passed to lookup | The promoCodes parameter is missing or empty. This is raised as a generic Error (not an RLE-coded error). |
Additional Considerations
- Validates promo codes parameter is provided
- Queries both PromoCode and PromoCodeDef collections
- Returns empty array if no matching codes found
- Supports both single code string and array of codes
- Populates definition details for each code
Lookup Promo Limits
Lookup Promo Limits¶
Description
The action is used to lookup and populate promotion rule limits for the current activity.
Parameters
None. Uses the current activity context.
JavaScript API
Outputs
Populates Context.promoRuleLimits with:
- Object mapping rule IDs to their limit objects
- Each limit contains: rule, redemptions, availableRedemptions, budgetUsed, availableBudget
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Filters limits by:
- Program from context member
- Not trashed
- Effective dates:
- effectiveTo is null or >= activity date
- canPreview is true or effectiveFrom <= activity date
- Returns empty object if no limits found
- Organizes limits by rule ID for easy lookup
- Supports preview mode through canPreview flag
Lookup Purse Policies
Lookup Purse Policies¶
Description
The action is used to lookup and populate purse policies based on lookup criteria.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Optional. Field to filter policies by |
| Lookup Values | String/Array | Text | Optional. Values to match against lookup field |
| Purse Policy Filter | Object | JSON | Optional. Additional filter criteria for policies |
JavaScript API
Outputs
Populates Context.pursePolicies with an array of purse policy objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- If lookup values provided but not array, splits on comma
- Trims whitespace from lookup values
- Combines lookup field filter with any additional filter criteria
- Always filters by program from context member
- Returns empty array if no policies found
- Combines with any existing purse policies in context
- Uses Map to deduplicate policies by ID
Lookup Reward Policies
Lookup Reward Policies¶
Description
The action is used to lookup and populate reward policies based on lookup criteria.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Required. Field to filter policies by. |
| Lookup Values | String/Array | Text | Optional. Values to match against lookup field. Comma-separated when supplied as a string. |
| Select Fields | String/Array | Text | Optional. Fields to include in returned policies. |
| Filter Type | String | Text | Optional. Restricts results by intendedUse — for example Reward or Offer. |
| Reward Policy Filter | Object | JSON | Optional. Additional filter criteria merged into the query. |
JavaScript API
UDF.populateRewardPolicies(lookupField, lookupValues, selectFields, filterType, rewardPolicyFilter, callback)
Outputs
Populates Context.activity.rewardPolicies with array of reward policy objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns early if lookup field not provided
- If lookup values provided but not array, splits on comma
- Trims whitespace from lookup values
- Returns empty array if no policies found
- Combines with any existing reward policies in context
- Uses Map to deduplicate policies by ID
- Supports field selection to limit returned data
Lookup Tier History
Lookup Tier History¶
Description
The action is used to lookup and populate tier history records for the current member.
Parameters
None. Uses the current member context.
JavaScript API
Outputs
Populates Context.member.tierHistory with array of tier history objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Filters tier history by member ID
- Combines with any existing tier history in context
- Returns empty array if no history found
- Uses concat to preserve order of history records
Lookup Tier Policies
Lookup Tier Policies¶
Description
The action is used to lookup and populate tier policies based on lookup criteria.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Lookup Field | String | Text | Optional. Field to filter policies by |
| Lookup Values | String/Array | Text | Optional. Values to match against lookup field |
| Select Fields | String/Array | Text | Optional. Fields to include in returned policies |
JavaScript API
Outputs
Populates Context.tierPolicies with array of tier policy objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- If lookup values provided but not array, splits on comma
- Trims whitespace from lookup values
- Returns empty array if no policies found
- Combines with any existing tier policies in context
- Uses Map to deduplicate policies by ID
- Supports field selection to limit returned data
Lookup User
Lookup User¶
Description
The action is used to lookup and populate user information for the current context.
Parameters
None. Uses the current user context.
JavaScript API
Outputs
Populates Context.user with the user object.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1007 | User not found | No user found in context or database |
Additional Considerations
- Returns early if no user is set on the context.
- Sets
Context.user.idto the user's_id.
Lookup Qualified Purses
Lookup Qualified Purses¶
Description
The action is used to lookup and populate qualified purses based on lookup criteria.
Parameters
| Parameter | Type | Description |
|---|---|---|
| Group Names | Multi-Select Searchable Dropdown | Used to select the group names from the drop-down |
JavaScript API
Outputs
Populates Context.qPurses with object key is group name and corresponding value is the qualified purse name.
qPurses: {
"Qualifying Nights": "Qualifying Nights 2025",
"Qualifying Spend": "Qualifying Spend 2025"
}
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- It retrieves qualified purses based on the selected groups.
- If no group names are selected, it fetches qualified purses from all groups within the program and assigns them to the qPurses in the context.
Segments & Preferences¶
Add Segment
Add Segment¶
Description
The action is used to add a segment to a member. Segments are used to group members based on defined criteria.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Segment | String | Dropdown | Select the segment to add to the member. If you want the segment name to be variable based on a calculated field, choose Variable in this drop down and fill in the Segment Name field that appears next to the dropdown. |
| Segment Name | String | Text | Required when Segment is Variable. The segment name resolved at run-time. |
| Segment Object | Object | JSON | Optional. Extra fields to merge into the segment record (for example a custom effectiveFrom/effectiveTo). |
Outputs
Returns the added segment object.
JavaScript API
Events Triggered
- Generates L1 ObjectInsertEvent when creating or updating segment record
- Generates L2 AddSegmentEvent when segment is added to member
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2130 | Segment is required | Reported when segmentId is missing. |
| 1574 | Segment not found | Reported when the segment ID (or name when Variable) doesn't resolve to a segment. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the segment. |
Additional Considerations
- In the Rule Builder the Segment name is a drop-down, showing all the Segments. You can select
Variableif you would like to compute theSegment Nameparameter at run-time. - Events are generated before database updates
- Updates member document with new segment
- Validates segment exists in program before adding
Remove Segment
Remove Segment¶
Description
The action is used to remove a segment from a member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Segment | String | Dropdown | Select the segment to remove from the member. If you want the segment name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Segment Name field that appears next to the dropdown. |
Outputs
Returns the removed segment object.
JavaScript API
Events Triggered
- Generates L1 ObjectDeleteEvent
- Generates L2 RemoveSegmentEvent
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1574 | Segment not found | Reported when the segment ID (or name when Variable) doesn't resolve to a segment on the member. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the segment. |
Additional Considerations
- In the Rule Builder the Segment name is a drop-down, showing all the Segments. You can select
Variableif you would like to compute theSegment Nameparameter at run-time. - Updates member document to remove the segment
- Validates segment exists before removing
Lookup Member Segments
Lookup Member Segments¶
Description
The action is used to lookup and populate segments associated with the current member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Name | String | Text | Optional. Name of segment to lookup. If not provided, returns all segments |
JavaScript API
Outputs
Populates Context.member.segments with array of segment objects.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. Any errors that occur are database errors propagated from the underlying MongoDB operations.
Additional Considerations
- Returns early if no member is found in context
- Filters segments by:
- Member ID
- Segment name if provided
- Handles cancelled segments by removing them from results
- Returns empty array if no segments found
Add Preference
Add Preference¶
Description
The action is used to add a preference to a member. Preferences can be configured with optional expiration dates and categories.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Preference Name | String | Text | Name of the preference to add |
| Preference Value | String | Text | Value to set for the preference |
| Optin Date | Date/Time | JS Date | Optional. When the preference was opted into |
| Expiration Date | Date/Time | JS Date | Optional. When the preference expires |
| Category | String | Text | Optional. Category for the preference. Defaults to 'Preference' |
Outputs
Returns the created preference object.
JavaScript API
Events Triggered
- Generates L1 ObjectInsertEvent when creating or updating preference
- Generates L2 AddPreferenceEvent when preference is added to member
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1661 | Invalid preference name | Reported if the preference name is invalid |
| 1662 | Invalid member ID for preference | Reported if the member ID is invalid |
Additional Considerations
- If no category is provided, defaults to 'Preference'
- Preferences are stored in a separate collection and linked to the member
- Updates existing preference if name already exists for member
- Automatically sets creation and update timestamps
- Events are generated before database updates
- Member document is updated to remove processed preferences
Remove Preference
Remove Preference¶
Description
The action is used to remove a preference from a member by its name.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Preference Name | String | Text | Name of the preference to remove |
Outputs
Returns the removed preference object.
JavaScript API
(At the rule-action layer, only prefName is meaningful — the action invokes UDF.removePreference(prefName, null, null, null, cb) internally.)
Events Triggered
- Generates L1 ObjectDeleteEvent
- Generates L2 RemovePreferenceEvent when preference is removed from member
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1661 | Invalid preference name | Reported if the preference name is invalid |
| 1662 | Invalid member ID for preference | Reported if the member ID is invalid |
Additional Considerations
- Preference is marked as cancelled in the preferences collection
- Member document is updated to remove the processed preference
- Events are generated before database updates
- Automatically sets update timestamp on the preference record
Streaks & Goals¶
Begin Streak
Begin Streak¶
Description
The action is used to start a new streak instance for a member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Opts | Object | Text | Optional. Options for starting the streak. See structure below. |
The Opts object can contain:
{
streakPolicyId: string, // Optional. ID of the streak policy. Defaults to current rule's streakPolicyId
startedAt: Date, // Optional. When the streak starts. Defaults to activity date
status: string, // Optional. Initial status. Defaults to 'Active'
value: number, // Optional. Initial value. Defaults to 0
errorOnExisting: boolean, // Optional. Whether to error if active streak exists. Defaults to false
errorOnInstanceLimit: boolean, // Optional. Whether to error if instance limit exceeded. Defaults to false
errorOnCoolOffTime: boolean, // Optional. Whether to error if cool off time not met. Defaults to false
goalValues: Array, // Optional. Override policy goal values if memLevelOverride flag is true
ctlGroup: any // Optional. Control group value
}
JavaScript API
Events Triggered
- Generates L2 StreakStartEvent when streak is started
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1790 | Unable to begin streak %s as it already exists in active status | An Active streak for this policy already exists on the member. Only thrown when errorOnExisting is true; otherwise the action is a no-op. |
| 1794 | Unable to begin streak %s as instance limit of %d exceeds %d | The streak's instance limit (policy.instanceLimit) is reached. Only thrown when errorOnInstanceLimit is true; otherwise the action emits StreakInstanceLimitExceededEvent and returns. |
| 1698 | %s streak cannot begin before %d minutes of previous streak completion | The previous instance ended inside the policy's coolOffTime window. Only thrown when errorOnCoolOffTime is true; otherwise the action emits StreakInstanceCoolOffSkipEvent and returns. |
| 1795 | Streak definition not found | Reported if the streak policy definition can't be resolved. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the streak policy. |
Additional Considerations
- Validates streak policy exists and is configured correctly
- Checks instance limits against policy settings
- Validates cool off time between streak instances
- Supports goal value overrides if policy allows
- Emits instance limit and cool off skip events when those conditions occur
Cancel Streak
Cancel Streak¶
Description
The action is used to cancel an active streak instance and all its goals.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Opts | Object | Text | Optional. Options for canceling the streak. See structure below. |
The Opts object can contain:
{
streakPolicyId: string, // Optional. ID of the streak policy. Defaults to current rule's streakPolicyId
date: Date // Optional. Date of cancellation. Defaults to activity date
}
JavaScript API
Events Triggered
- Generates L2 StreakCancelEvent when streak is cancelled
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4033 | Options must be an object in the Cancel Streak action | opts is not an object (or is an array). |
| 1792 | No active streak | Reported if there is no Active streak for the resolved policy on the member. |
| 1795 | Streak definition not found | Reported if the streak policy definition can't be resolved. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the streak policy. |
Additional Considerations
- Sets streak status to 'Cancelled'
- Sets all active goals to 'Cancelled'
- Sets cancellation date on streak and all goals
- Only cancels streaks that are in 'Active' status
Evaluate Streak
Evaluate Streak¶
Description
The action is used to evaluate active goals and the overall streak status.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Opts | Object | Text | Optional. Options for streak evaluation. See structure below. |
The Opts object can contain:
{
streakPolicyId: string, // Optional. ID of the streak policy. Defaults to current rule's streakPolicyId
date: Date, // Optional. Date of evaluation. Defaults to activity date
postEndEval: boolean // Optional. Indicates evaluation is running after end date. Defaults to false
}
JavaScript API
Events Triggered
- Generates L2 StreakGoalExpirationEvent when a goal expires
- Generates L2 StreakGoalCompletionEvent when a goal completes
- Generates L2 StreakExpirationEvent when streak expires
- Generates L2 StreakCompletionEvent when streak completes
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1792 | Streak "%s" does not exist or is not active | Reported if there is no active streak for the member |
| 1795 | Unable to locate streak definition for policy "%s" | Reported if the streak policy definition can't be found |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the streak policy |
Additional Considerations
- Evaluates completion and expiration of both goals and overall streak
- Goals can expire based on time limits from streak start or goal start
- Streak completes when required number of goals are completed
- Streak expires if too many goals expire to meet completion requirements
- All goal statuses are evaluated before streak status
Advance Streak Goal
Advance Streak Goal¶
Description
The action is used to advance a member's streak goal value when they perform a qualifying activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Opts | Object | Text | Optional. Options for advancing the streak goal. See structure below. |
The Opts object can contain:
{
streakPolicyId: string, // Optional. ID of the streak policy. Defaults to current rule's streakPolicyId
goalName: string, // Optional. Name of the goal to advance. Defaults to current rule's goalName
date: Date, // Optional. Date of the advancement. Defaults to activity date
value: number, // Optional. Value to add to goal. Defaults to 0
consumeRemainder: boolean // Optional. Whether to consume remainder after reaching target. Defaults to false
}
JavaScript API
Events Triggered
- Generates L2 StreakGoalAdvanceEvent when goal value is advanced
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1791 | Goal not advanced | Reported if the goal couldn't be advanced |
| 1792 | No active streak | Reported if there is no active streak for the member |
| 1793 | Goal not found | Reported if the specified goal isn't found |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the streak policy |
Additional Considerations
- Only advances the goal if member has an active streak
- Validates goal exists before advancing
- Only emits event if goal value actually changes
- If consumeRemainder is false, any value above the goal target is returned as remainder
- Goal value is rounded to streak policy's precision setting
Badges & Tiers¶
Give Badge
Give Badge¶
Description
The action is used to add a badge to a member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Badge Name | String | Text | The name of the badge to add |
JavaScript API
Events Triggered
- Generates L2 AddBadgeEvent when badge is added
Possible Errors
| Error Code | Error Message | Description | |-|-|-|-| | 1524 | Please use unique badge name for field name | Reported if member already has a badge with the given name |
Additional Considerations
- Includes activity ID, rule ID, and timestamps in badge metadata
- Badge is added to member.badges array
Set Tier
Set Tier¶
Description
The action sets a specific tier level for a member, with optional expiration and lock dates.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Tier | Dropdown | String | The tier policy name |
| Level | Dropdown | String | The name of the level to set. If you want the level name to be variable based on a calculated field, choose the Variable in this drop down and fill in the Level Name field that appears next to the dropdown. |
| Requalification Date | Date/Time | JS Date | Optional. Date when member needs to requalify |
| Achievement Date | Date/Time | JS Date | Optional. Date when level was achieved |
| Lock Date | Date/Time | JS Date | Optional. Date until which tier is locked |
| Reason | String | Text | Optional. Reason for tier change |
| Sub Reason | String | Text | Optional. Additional reason details |
JavaScript API
(At the rule-action layer the engine accepts an additional levelName parameter between level and requalsOn. When the rule UI sets Level to Variable, the action uses the supplied Level Name as the actual level; otherwise levelName is null. The action detects callers that omit levelName (older rules) and shifts arguments forward for backward compatibility.)
Events Triggered
Generates the L2 SetTierEvent for the member.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 1733 | No permission to adjust tiers | Current user lacks update permission on the TierAdjustment resource. |
| 1824 | Tier is required | policyId is missing. |
| 1737 | Please provide the correct level name for Tier Policy: %s and ID: %s | When Level is Variable and no Level Name is supplied. |
| 2045 | Could not find tier in member with _id %s | The tier for the given policy ID isn't on the member. |
| 2047 | Tier policy with id %s and program %s does not have level with value %s | The supplied level isn't defined on the tier policy. |
| 4041 | Division Access Denied for user | Reported when user lacks division access for the tier policy. |
Flow Control¶
Custom Action
Custom Action¶
Description
The action is used to execute custom JavaScript code with access to the member context.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Custom action | Function | Text | JavaScript function to execute. Must follow format: function(param, context, callback) |
| Parameter | Any | Text | Parameter value passed to the custom action function |
JavaScript API
This action doesn't have a JS API.
Events Triggered
- Generates L2 CustomActionEvent if the action generates custom event data
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2010 | Custom Action needs to be a function | Reported when the supplied customAction does not evaluate to a function. |
| (propagated) | (any) | Errors thrown by the custom action's JavaScript propagate to the rule engine; their codes depend on what the custom code throws (or calls UDF.throwError with). |
Additional Considerations
- Custom action function must follow the signature:
function(param, context, callback) - Function must call callback(error) for failures or callback(null) for success
- Has access to full member context through the context parameter
- Custom JavaScript validation is performed before execution
- Function runs in a sandboxed environment with limited global access
Do Not Fire Rule
Do Not Fire Rule¶
Description
The action is used to prevent a specific rule from firing in the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Rule Name | String | Dropdown | Select the rule to prevent from firing |
JavaScript API
Events Triggered
No events are generated by this action.
Possible Errors
This action does not throw errors. Supplying an unknown rule name silently sets a suppression flag — if no rule of that name matches during the flow, the flag has no effect.
Additional Considerations
- Only affects rule execution for the current activity.
- Doesn't modify the rule definition.
- Suppression applies to subsequent rule firings in this flow. Rules that have already fired earlier in the same activity are not retroactively undone.
Throw Error
Throw Error¶
Description
The action is used to explicitly throw an error with a custom message and code.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Error Message | String | Text | Custom error message to display |
| Code | Number | Integer | Optional. Error code to attach to the thrown error. If omitted, the error is thrown with an undefined code field. |
| HTTP Status Code | Number | Integer | Optional. HTTP status code to return |
| Display Error Context | Boolean | Text | Optional. Whether to include rule context in error. Defaults to true |
JavaScript API
Outputs
None. The action throws an error and stops execution.
Events Triggered
No events are generated by this action.
Possible Errors
This action always throws an error with:
Code: The provided code, or undefined if not supplied.Message: The provided error message (defaults to "Errors occurred while executing rules." when omitted).HTTP Status: The provided status code, or 500 if not specified.Context: Rule name and failed element are appended whendisplayErrorContextis true.
Additional Considerations
- Logs error before throwing.
- Error is constructed using engine.execution error type.
- Error includes rule context by default.
- Can be used for custom validation or business logic errors.
- Stops rule execution when thrown.
- Errors are caught by the rule engine and returned to the client.
Override No of Executions
Override No Of Executions¶
Description
The action is used to override the number of times a rule was considered matched and executed for the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Execution Count | Number | Integer | Optional. Number of times to count the rule as executed. Defaults to 1 |
JavaScript API
Outputs
Sets the execution count for the rule on the current activity. Subsequent point/reward operations in the rule will scale by this count (for example, "add 10 points" with an execution count of 3 adds 30 points).
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action.
Additional Considerations
- If
executionCountisn't provided, defaults to 1. - Affects how many times subsequent actions in the same rule execute.
- Useful for testing and debugging rule execution flows.
- Changes apply only to the current activity.
Add New Relic Attributes
Add New Relic Attributes¶
Description
Attaches custom attributes to the current New Relic transaction for APM/observability. Use to annotate rule executions with business-meaningful tags (member tier, campaign code, rule outcome, etc.) so they can be queried in NRQL.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Data | Object | JSON | Object of {key: value} pairs to attach as custom attributes on the current New Relic transaction. Non-object values, empty objects, and null are silently ignored. |
JavaScript API
Outputs
None. The action only emits APM metadata; it doesn't change activity or member state.
Events Triggered
No events are generated by this action.
Possible Errors
This action does not throw any errors. If the New Relic agent isn't loaded in the current environment, the call is a no-op.
Additional Considerations
- Attributes attach to the current transaction trace; they are not persistent storage.
- Per New Relic conventions, attribute values should be strings, numbers, or booleans. Nested objects may be flattened or truncated.
- The action is a no-op when
datais missing, empty, or not an object — no warning is logged.
Results & Updates¶
Get Results
Get Results¶
Description
The action is used to retrieve sections of the activity result.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Section | String | Text | The section to retrieve ('data', 'log', 'errors', or any other value for full result) |
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
This action doesn't throw any errors.
Additional Considerations
- Section parameter is case-insensitive
- Returns specific section for 'data', 'log', or 'errors'
- Returns entire result object for any other section value
- Returns undefined if requested section doesn't exist
Set Results
Set Results¶
Description
The action is used to set results data in the context for the current activity.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Section | String | Text | Section to update ('log', 'errors', 'data', or entire result) |
| Data | Any | JSON | Data to set in the specified section |
JavaScript API
Outputs
Updates Context.result based on section:
- 'log' or 'errors': Sets array in
Context.result[log or errors] - 'data': Sets data in
Context.result.data - other: Sets entire
Context.resultobject
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action. JSON.parse() may throw errors if invalid JSON strings are provided.
Additional Considerations
- Section parameter is case-insensitive
- For 'log' or 'errors' sections:
- Single items are wrapped in array
- String data is parsed as JSON
- For 'data' section:
- String data is parsed as JSON
- Replaces entire data section
- For other sections:
- Replaces entire result object
- String data is parsed as JSON
- No validation of data structure or content
Extend Results
Extend Results¶
Description
The action is used to extend the activity result with additional data.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Section | String | Text | The section to extend ('data', 'log', or 'errors') |
| Data | Object | Text | The data to merge into the result section |
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
This action doesn't throw any errors.
Additional Considerations
- Section parameter is case-insensitive.
- For
logorerrors: data is wrapped in an array if it isn't already, and the resulting items are appended to the existing array. - For
data: the supplied object is shallow-merged intoContext.result.data(existing keys are overwritten when they conflict). - For any other section value: the supplied object is shallow-merged into the entire
Context.resultobject. - String data is parsed as JSON before merging.
Set Persist
Set Persist¶
Description
The action is used to control whether the current activity is persisted.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Flag | Boolean | Text | Whether to persist the activity |
JavaScript API
Outputs
Sets Context.persistAct to the provided flag value.
Events Triggered
No events are generated by this action.
Possible Errors
No errors are thrown directly by this action.
Additional Considerations
- Sets whether the current activity is persisted.
- Callback parameter is optional.
- Changes only affect current activity.
- Useful for testing and debugging scenarios where you don't want activities saved.
- Has no effect on other persistence like member updates.
Extend Activity Result Log
Extend Activity Result Log¶
Description
The action is used to extend the activity result log data with additional fields.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Data | Object | Text | The data to merge into the activity result log |
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
This action doesn't throw any errors.
Additional Considerations
- The
dataparameter can be a string (parsed as JSON) or an object. - Merges data into
Context.resultLogData.
Update Member Offer
Update Member Offer¶
Description
The action is used to update properties of an existing offer associated with the member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Offer Code | String | Text | Code of the offer to update |
| Offer Object | Object | JSON | Object containing fields to update |
JavaScript API
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4041 | Division Access Denied for user | Reported when user lacks division access for the offer |
Additional error handling: - Logs a warning and returns if the offer code isn't provided. - Logs a warning and returns if no matching offers are found. - Passes through any database errors from MongoDB operations.
Additional Considerations
- Returns if the offer code isn't provided.
- Returns if no matching offer is found on the member.
- Sets
updatedAtandupdatedByautomatically. - Preserves existing offer fields not specified in the update object.
Update Member Reward
Update Member Reward¶
Description
The action is used to update properties of an existing reward associated with the member.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Reward Code | String | Text | Code of the reward to update |
| Reward Object | Object | JSON | Object containing fields to update |
JavaScript API
Outputs
Returns the updated reward object.
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 4041 | Division Access Denied for user | Reported when user lacks division access for the reward |
Additional error handling: - Logs a warning and returns if the reward code isn't provided. - Logs a warning and returns if no matching reward is found. - Passes through any database errors from MongoDB operations.
Additional Considerations
- Returns if the reward code isn't provided.
- Returns if no matching reward is found on the member.
- Sets
updatedAtandupdatedByautomatically. - Preserves existing reward fields not specified in the update object.
Referrals¶
Generate Referral Code
Generate Referral Code¶
Description
The action is used to generate a unique referral code for a member.
Parameters
This action takes no parameters.
Outputs
Sets the member.referralCode value.
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
This action doesn't throw any errors.
Additional Considerations
- Only generates new code if member doesn't already have one
- Uses nanoid() to generate unique codes
Lookup Referrer
Lookup Referrer By Code¶
Description
The action is used to lookup and populate referrer member information using a referral code. This is useful when an enrollment happens with a referralCode that was issued by another member. This action loads that member into the context.
Parameters
| Parameter | Type | Format | Description |
|---|---|---|---|
| Referral Code | String | Text | Code to lookup referrer by |
JavaScript API
Outputs
Populates Context with:
referrerMember: The referrer member objectreferrerLoyaltyId: The referrer's loyalty ID if found
Events Triggered
No events are generated by this action.
Possible Errors
| Error Code | Error Message | Description |
|---|---|---|
| 2084 | Referrer with code %s not found. | No member matched the supplied referralCode. |
Additional Considerations
- Returns early if no referral code provided.
- Looks up loyalty ID for referrer if available.
- Returns if loyalty ID not found.
User Management¶
Get User Roles
Get User Roles¶
Description
The action is used to retrieve the roles assigned to the current user.
Parameters
This action takes no parameters.
Output
Sets Context.user.roles with the retrieved roles as an array.
JavaScript API
Events Triggered
No events are generated by this action
Possible Errors
This action propagates any errors from the ACL system but doesn't directly throw any errors.
Additional Considerations
- Sets
Context.user.roles with the retrieved roles - Returns both user login and roles array in result
- Returns empty array for roles if none are found
- Uses the current user's login from cls context